From patchwork Tue Feb 27 17:53:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dufresne X-Patchwork-Id: 19562 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 588DDBD160 for ; Tue, 27 Feb 2024 17:54:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1ADDC62867; Tue, 27 Feb 2024 18:54:02 +0100 (CET) Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [IPv6:2a00:1098:ed:100::25]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 04B2E6285F for ; Tue, 27 Feb 2024 18:54:00 +0100 (CET) Received: from nicolas-tpx395.lan (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nicolas) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 32447378000B; Tue, 27 Feb 2024 17:53:59 +0000 (UTC) From: Nicolas Dufresne To: libcamera-devel@lists.libcamera.org Subject: [PATCH v1 1/3] gstreamer: allocator: Ensure camera manager stay alive Date: Tue, 27 Feb 2024 12:53:34 -0500 Message-ID: <20240227175336.560009-2-nicolas@ndufresne.ca> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240227175336.560009-1-nicolas@ndufresne.ca> References: <20240227175336.560009-1-nicolas@ndufresne.ca> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nicolas Dufresne Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Nicolas Dufresne With 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. Fixes: Bugzilla issue 211 Signed-off-by: Nicolas Dufresne --- src/gstreamer/gstlibcameraallocator.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gstreamer/gstlibcameraallocator.cpp b/src/gstreamer/gstlibcameraallocator.cpp index c740b8fc..844bdb17 100644 --- a/src/gstreamer/gstlibcameraallocator.cpp +++ b/src/gstreamer/gstlibcameraallocator.cpp @@ -100,6 +100,11 @@ struct _GstLibcameraAllocator { * FrameWrap. */ GHashTable *pools; + /* + * The camera manager represent that library, which needs to be kept alive + * until all the memory have been released. + */ + std::shared_ptr *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, { auto *self = GST_LIBCAMERA_ALLOCATOR(g_object_new(GST_TYPE_LIBCAMERA_ALLOCATOR, nullptr)); + gint ret; + + self->cm_ptr = new std::shared_ptr(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) From patchwork Tue Feb 27 17:53:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dufresne X-Patchwork-Id: 19563 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 47D5AC3264 for ; Tue, 27 Feb 2024 17:54:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5BC0D62877; Tue, 27 Feb 2024 18:54:02 +0100 (CET) Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [IPv6:2a00:1098:ed:100::25]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 69DC762865 for ; Tue, 27 Feb 2024 18:54:01 +0100 (CET) Received: from nicolas-tpx395.lan (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nicolas) by madrid.collaboradmins.com (Postfix) with ESMTPSA id CBFFF378000B; Tue, 27 Feb 2024 17:54:00 +0000 (UTC) From: Nicolas Dufresne To: libcamera-devel@lists.libcamera.org Subject: [PATCH v1 2/3] test: gstreamer: Simplify single stream test Date: Tue, 27 Feb 2024 12:53:35 -0500 Message-ID: <20240227175336.560009-3-nicolas@ndufresne.ca> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240227175336.560009-1-nicolas@ndufresne.ca> References: <20240227175336.560009-1-nicolas@ndufresne.ca> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nicolas Dufresne Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Nicolas Dufresne Signed-off-by: Nicolas Dufresne --- .../gstreamer_single_stream_test.cpp | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp b/test/gstreamer/gstreamer_single_stream_test.cpp index 301e4a93..815c6609 100644 --- a/test/gstreamer/gstreamer_single_stream_test.cpp +++ b/test/gstreamer/gstreamer_single_stream_test.cpp @@ -29,30 +29,21 @@ protected: if (status_ != TestPass) return status_; - const gchar *streamDescription = "fakesink"; - g_autoptr(GError) error0 = NULL; - stream0_ = gst_parse_bin_from_description_full(streamDescription, TRUE, - NULL, - GST_PARSE_FLAG_FATAL_ERRORS, - &error0); - - if (!stream0_) { - g_printerr("Bin could not be created (%s)\n", error0->message); + fakesink_ = gst_element_factory_make("fakesink", nullptr); + if (!fakesink_) { + g_printerr("Your installation is missing 'fakesink'\n"); return TestFail; } - g_object_ref_sink(stream0_); - - if (createPipeline() != TestPass) - return TestFail; + g_object_ref_sink(fakesink_); - return TestPass; + return createPipeline(); } int run() override { /* Build the pipeline */ - gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, stream0_, NULL); - if (gst_element_link(libcameraSrc_, stream0_) != TRUE) { + gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, fakesink_, nullptr); + if (!gst_element_link(libcameraSrc_, fakesink_)) { g_printerr("Elements could not be linked.\n"); return TestFail; } @@ -68,11 +59,11 @@ protected: void cleanup() override { - g_clear_object(&stream0_); + g_clear_object(&fakesink_); } private: - GstElement *stream0_; + GstElement *fakesink_; }; TEST_REGISTER(GstreamerSingleStreamTest) From patchwork Tue Feb 27 17:53:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dufresne X-Patchwork-Id: 19564 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CBC95BD160 for ; Tue, 27 Feb 2024 17:54:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A830862875; Tue, 27 Feb 2024 18:54:04 +0100 (CET) Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [IPv6:2a00:1098:ed:100::25]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B75CD62876 for ; Tue, 27 Feb 2024 18:54:02 +0100 (CET) Received: from nicolas-tpx395.lan (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nicolas) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 2670E378000B; Tue, 27 Feb 2024 17:54:02 +0000 (UTC) From: Nicolas Dufresne To: libcamera-devel@lists.libcamera.org Subject: [PATCH v1 3/3] test: gstreamer: Test memory lifetime Date: Tue, 27 Feb 2024 12:53:36 -0500 Message-ID: <20240227175336.560009-4-nicolas@ndufresne.ca> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240227175336.560009-1-nicolas@ndufresne.ca> References: <20240227175336.560009-1-nicolas@ndufresne.ca> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nicolas Dufresne Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Nicolas Dufresne Test that everything works fine if a buffer outlives the pipeline. Signed-off-by: Nicolas Dufresne --- .../gstreamer_memory_lifetime_test.cpp | 75 +++++++++++++++++++ test/gstreamer/meson.build | 4 +- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 test/gstreamer/gstreamer_memory_lifetime_test.cpp diff --git a/test/gstreamer/gstreamer_memory_lifetime_test.cpp b/test/gstreamer/gstreamer_memory_lifetime_test.cpp new file mode 100644 index 00000000..8842a826 --- /dev/null +++ b/test/gstreamer/gstreamer_memory_lifetime_test.cpp @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2021, Vedant Paranjape + * + * gstreamer_single_stream_test.cpp - GStreamer single stream capture test + */ + +#include +#include + +#include +#include + +#include "gstreamer_test.h" +#include "test.h" + +using namespace std; + +class GstreamerMemoryLifetimeTest : public GstreamerTest, public Test +{ +public: + GstreamerMemoryLifetimeTest() + : GstreamerTest() + { + } + +protected: + int init() override + { + if (status_ != TestPass) + return status_; + + appsink_ = gst_element_factory_make("appsink", nullptr); + if (!appsink_) { + g_printerr("Your installation is missing 'appsink'\n"); + return TestFail; + } + g_object_ref_sink(appsink_); + + return createPipeline(); + } + + int run() override + { + /* Build the pipeline */ + gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, appsink_, nullptr); + if (gst_element_link(libcameraSrc_, appsink_) != TRUE) { + g_printerr("Elements could not be linked.\n"); + return TestFail; + } + + if (startPipeline() != TestPass) + return TestFail; + + sample_ = gst_app_sink_try_pull_sample(GST_APP_SINK(appsink_), GST_SECOND * 5); + gst_element_set_state(pipeline_, GST_STATE_NULL); + + if (!sample_) + return TestFail; + + return TestPass; + } + + void cleanup() override + { + g_clear_pointer(&sample_, gst_sample_unref); + g_clear_object(&appsink_); + } + +private: + GstElement *appsink_; + GstSample *sample_; +}; + +TEST_REGISTER(GstreamerMemoryLifetimeTest) diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build index f3ba5a23..70609b88 100644 --- a/test/gstreamer/meson.build +++ b/test/gstreamer/meson.build @@ -8,12 +8,14 @@ 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']}, ] gstreamer_dep = dependency('gstreamer-1.0', required : true) +gstapp_dep = dependency('gstreamer-app-1.0', required : true) foreach test : gstreamer_tests exe = executable(test['name'], test['sources'], 'gstreamer_test.cpp', - dependencies : [libcamera_private, gstreamer_dep], + dependencies : [libcamera_private, gstreamer_dep, gstapp_dep], link_with : test_libraries, include_directories : test_includes_internal)