[v1,3/3] test: gstreamer: Test memory lifetime
diff mbox series

Message ID 20240227175336.560009-4-nicolas@ndufresne.ca
State Superseded
Headers show
Series
  • gstreamer: Fix a crash when memory outlives the pipeline
Related show

Commit Message

Nicolas Dufresne Feb. 27, 2024, 5:53 p.m. UTC
From: Nicolas Dufresne <nicolas.dufresne@collabora.com>

Test that everything works fine if a buffer outlives the pipeline.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
 .../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

Comments

Nicolas Dufresne Feb. 27, 2024, 5:59 p.m. UTC | #1
Le mardi 27 février 2024 à 12:53 -0500, Nicolas Dufresne a écrit :
> From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> 
> Test that everything works fine if a buffer outlives the pipeline.
> 
> Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> ---
>  .../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

* Copyright (C) 2024, Nicolas Dufresne

> + *
> + * gstreamer_single_stream_test.cpp - GStreamer single stream capture test

* gstreamer_memory_lifetime_test.cpp - GStreamer memory lifetime test

Sorry about these.

Nicolas

> + */
> +
> +#include <iostream>
> +#include <unistd.h>
> +
> +#include <gst/app/app.h>
> +#include <gst/gst.h>
> +
> +#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)
>

Patch
diff mbox series

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 <iostream>
+#include <unistd.h>
+
+#include <gst/app/app.h>
+#include <gst/gst.h>
+
+#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)