[libcamera-devel] [PATCH v1] test: gstreamer: Add a test for gstreamer multi stream
Nicolas Dufresne
nicolas.dufresne at collabora.com
Thu Sep 23 15:07:56 CEST 2021
Le jeudi 23 septembre 2021 à 16:35 +0530, Vedant Paranjape a écrit :
> This patch adds a test to test if multi stream using libcamera's
> gstreamer element works.
>
> Test will run only on devices that support multistream output, i.e.,
> devices that use IPU3 and raspberrypi pipeline. This was tested on
> a Raspberry Pi 4B+.
>
> Signed-off-by: Vedant Paranjape <vedantparanjape160201 at gmail.com>
> ---
>
> I am unable to run Valgrind on my RPI4B+, please check for memory
> leaks on RPI4B+ as well. I used the following steps to test on amd64
> system using the suppression files.
>
> <snip>
> cd libcamera
> wget https://cgit.freedesktop.org/gstreamer/common/plain/gst.supp -P /tmp
> ninja -C build test
> valgrind --leak-check=full --suppressions=/usr/share/glib-2.0/valgrind/glib.supp --suppressions=/tmp/gst.supp ./build/test/gstreamer/single_stream_test
> valgrind --leak-check=full --suppressions=/usr/share/glib-2.0/valgrind/glib.supp --suppressions=/tmp/gst.supp ./build/test/gstreamer/multi_stream_test
> <snip>
>
> Also please test this test on IPU3 enabled devices too, as I don't have
> access to the same.
>
> ---
> .../gstreamer/gstreamer_multi_stream_test.cpp | 118 ++++++++++++++++++
> test/gstreamer/meson.build | 1 +
> 2 files changed, 119 insertions(+)
> create mode 100644 test/gstreamer/gstreamer_multi_stream_test.cpp
>
> diff --git a/test/gstreamer/gstreamer_multi_stream_test.cpp b/test/gstreamer/gstreamer_multi_stream_test.cpp
> new file mode 100644
> index 000000000000..76cf5a3418a1
> --- /dev/null
> +++ b/test/gstreamer/gstreamer_multi_stream_test.cpp
> @@ -0,0 +1,118 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2021, Vedant Paranjape
> + *
> + * gstreamer_multi_stream_test.cpp - GStreamer multi stream capture test
> + */
> +
> +#include <iostream>
> +#include <unistd.h>
> +
> +#include <libcamera/base/utils.h>
> +
> +#include <libcamera/libcamera.h>
> +
> +#include "libcamera/internal/source_paths.h"
> +
> +#include <gst/gst.h>
> +
> +#include "gstreamer_test.h"
> +#include "test.h"
> +
> +using namespace std;
> +
> +class GstreamerMultiStreamTest : public GstreamerTest, public Test
> +{
> +public:
> + GstreamerMultiStreamTest()
> + : GstreamerTest()
> + {
> + }
> +
> +protected:
> + int init() override
> + {
> + if (status_ != TestPass)
> + return status_;
> +
> + /* Check if platform support multistream output */
> + libcamera::CameraManager cm;
> + cm.start();
> + bool cameraFound = false;
> + for (auto &camera : cm.cameras()) {
> + if (camera->streams().size() > 1) {
> + cameraName = camera->id();
> + cameraFound = true;
> + cm.stop();
> + break;
> + }
> + }
> +
> + if (!cameraFound) {
> + cm.stop();
> + return TestSkip;
> + }
> +
> + const gchar *streamDescription = "queue ! videoconvert ! fakesink";
Converter could be removed, it will always passthrough.
> + g_autoptr(GError) error0 = NULL;
> + g_autoptr(GError) error1 = NULL;
> + stream0_ = gst_parse_bin_from_description_full(streamDescription, TRUE, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &error0);
> + stream1_ = gst_parse_bin_from_description_full(streamDescription, TRUE, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &error1);
> +
> + if (!stream0_ || !stream1_) {
> + g_printerr("Not all bins could be created. %p.%p\n",
> + stream0_, stream1_);
Please, split this in two checks, so you can dump the appropriate error message.
> + return TestFail;
> + }
> + g_object_ref_sink(stream0_);
> + g_object_ref_sink(stream1_);
> +
> + if (createPipeline() != TestPass)
> + return TestFail;
> +
> + return TestPass;
> + }
> +
> + int run() override
> + {
> + g_object_set(libcameraSrc_, "camera-name", cameraName.c_str(), NULL);
> +
> + /* Build the pipeline */
> + gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,
> + stream0_, stream1_, NULL);
> +
> + g_autoptr(GstPad) src_pad = gst_element_get_static_pad(libcameraSrc_, "src");
> + g_autoptr(GstPad) request_pad = gst_element_get_request_pad(libcameraSrc_, "src_%u");
> +
> + {
> + g_autoptr(GstPad) queue0_sink_pad = gst_element_get_static_pad(stream0_, "sink");
> + g_autoptr(GstPad) queue1_sink_pad = gst_element_get_static_pad(stream1_, "sink");
> +
> + if (gst_pad_link(src_pad, queue0_sink_pad) != GST_PAD_LINK_OK
> + || gst_pad_link(request_pad, queue1_sink_pad) != GST_PAD_LINK_OK) {
> + g_printerr("Pads could not be linked.\n");
> + return TestFail;
> + }
> + }
> +
> + if (startPipeline() != TestPass)
> + return TestFail;
> +
> + if (processEvent() != TestPass)
> + return TestFail;
> +
> + return TestPass;
> + }
> +
> + void cleanup() override
> + {
> + g_clear_object(&stream0_);
> + g_clear_object(&stream1_);
> + }
> +private:
> + std::string cameraName;
> + GstElement *stream0_;
> + GstElement *stream1_;
> +};
> +
> +TEST_REGISTER(GstreamerMultiStreamTest)
> diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build
> index aca53b920365..13652e87d05c 100644
> --- a/test/gstreamer/meson.build
> +++ b/test/gstreamer/meson.build
> @@ -6,6 +6,7 @@ endif
>
> gstreamer_tests = [
> ['single_stream_test', 'gstreamer_single_stream_test.cpp'],
> + ['multi_stream_test', 'gstreamer_multi_stream_test.cpp'],
> ]
> gstreamer_dep = dependency('gstreamer-1.0', required: true)
Looks good with that minor change.
Reviewed-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
>
More information about the libcamera-devel
mailing list