new file mode 100644
@@ -0,0 +1,138 @@
+/* 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 &i : cm.cameras()) {
+ if (i->streams().size() > 1) {
+ cameraName = i->id();
+ cameraFound = true;
+ cm.stop();
+ break;
+ }
+ }
+
+ if (!cameraFound) {
+ cm.stop();
+ return TestSkip;
+ }
+
+ g_autoptr(GstElement) convert0 = gst_element_factory_make("videoconvert", "convert0");
+ g_autoptr(GstElement) convert1 = gst_element_factory_make("videoconvert", "convert1");
+ g_autoptr(GstElement) sink0 = gst_element_factory_make("fakesink", "sink0");
+ g_autoptr(GstElement) sink1 = gst_element_factory_make("fakesink", "sink1");
+ g_autoptr(GstElement) queue0 = gst_element_factory_make("queue", "queue0");
+ g_autoptr(GstElement) queue1 = gst_element_factory_make("queue", "queue1");
+ g_object_ref_sink(convert0);
+ g_object_ref_sink(convert1);
+ g_object_ref_sink(sink0);
+ g_object_ref_sink(sink1);
+ g_object_ref_sink(queue0);
+ g_object_ref_sink(queue1);
+
+ if (!convert0 || !convert1 || !sink0 || !sink1 || !queue0 || !queue1) {
+ g_printerr("Not all elements could be created. %p.%p.%p.%p.%p.%p\n",
+ convert0, convert1, sink0, sink1, queue0, queue1);
+
+ return TestFail;
+ }
+
+ convert0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&convert0));
+ convert1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&convert1));
+ sink0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&sink0));
+ sink1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&sink1));
+ queue0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&queue0));
+ queue1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&queue1));
+
+ 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_, queue0_, queue1_,
+ convert0_, convert1_, sink0_, sink1_, NULL);
+ if (gst_element_link_many(queue0_, convert0_, sink0_, NULL) != TRUE
+ || gst_element_link_many(queue1_, convert1_, sink1_, NULL) != TRUE) {
+ g_printerr("Elements could not be linked.\n");
+ return TestFail;
+ }
+
+ 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");
+ GstPad *queue0_sink_pad = gst_element_get_static_pad(queue0_, "sink");
+ GstPad *queue1_sink_pad = gst_element_get_static_pad(queue1_, "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) {
+ if (queue0_sink_pad)
+ gst_object_unref(queue0_sink_pad);
+ if (queue1_sink_pad)
+ gst_object_unref(queue1_sink_pad);
+ g_printerr("Pads could not be linked.\n");
+ return TestFail;
+ }
+ gst_object_unref(queue0_sink_pad);
+ gst_object_unref(queue1_sink_pad);
+
+ if (startPipeline() != TestPass)
+ return TestFail;
+
+ if (processEvent() != TestPass)
+ return TestFail;
+
+ return TestPass;
+ }
+
+private:
+ std::string cameraName;
+ GstElement *convert0_;
+ GstElement *convert1_;
+ GstElement *sink0_;
+ GstElement *sink1_;
+ GstElement *queue0_;
+ GstElement *queue1_;
+};
+
+TEST_REGISTER(GstreamerMultiStreamTest)
@@ -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)