Message ID | 20210923110518.1556973-1-vedantparanjape160201@gmail.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
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@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@collabora.com> >
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"; + 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_); + 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)
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@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