Move the logic for checking the availability of cameras from multi_stream_test to gstreamer test base class. Since single_stream_class always assumes that a camera is available on the system (which is not always the case for e.g. RPi in CI/CD environments) it makes sense to have the availability check in the base class. If no cameras are available, the behaviour should be to skip instead of a failure. We currently have 2 tests for gstreamer differing based on number of streams supported by the camera. Hence, the camera availability is checked in conjunction with the number of the streams required by the derived class. Signed-off-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
114 lines
2.6 KiB
C++
114 lines
2.6 KiB
C++
/* 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/libcamera.h>
|
|
|
|
#include <gst/gst.h>
|
|
|
|
#include "gstreamer_test.h"
|
|
#include "test.h"
|
|
|
|
#if !GST_CHECK_VERSION(1, 19, 1)
|
|
static inline GstPad *gst_element_request_pad_simple(GstElement *element,
|
|
const gchar *name)
|
|
{
|
|
return gst_element_get_request_pad(element, name);
|
|
}
|
|
#endif
|
|
|
|
using namespace std;
|
|
|
|
class GstreamerMultiStreamTest : public GstreamerTest, public Test
|
|
{
|
|
public:
|
|
GstreamerMultiStreamTest()
|
|
: GstreamerTest(2)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
int init() override
|
|
{
|
|
if (status_ != TestPass)
|
|
return status_;
|
|
|
|
const gchar *streamDescription = "queue ! fakesink";
|
|
g_autoptr(GError) error = NULL;
|
|
|
|
stream0_ = gst_parse_bin_from_description_full(streamDescription, TRUE,
|
|
NULL,
|
|
GST_PARSE_FLAG_FATAL_ERRORS,
|
|
&error);
|
|
if (!stream0_) {
|
|
g_printerr("Stream0 could not be created (%s)\n", error->message);
|
|
return TestFail;
|
|
}
|
|
g_object_ref_sink(stream0_);
|
|
|
|
stream1_ = gst_parse_bin_from_description_full(streamDescription, TRUE,
|
|
NULL,
|
|
GST_PARSE_FLAG_FATAL_ERRORS,
|
|
&error);
|
|
if (!stream1_) {
|
|
g_printerr("Stream1 could not be created (%s)\n", error->message);
|
|
return TestFail;
|
|
}
|
|
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_request_pad_simple(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)
|