From patchwork Thu Sep 23 11:05:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vedant Paranjape X-Patchwork-Id: 13907 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E336DBF01C for ; Thu, 23 Sep 2021 11:05:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 484046918C; Thu, 23 Sep 2021 13:05:38 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="C+aNMwvy"; dkim-atps=neutral Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1EDA169189 for ; Thu, 23 Sep 2021 13:05:37 +0200 (CEST) Received: by mail-pf1-x432.google.com with SMTP id w19so5351533pfn.12 for ; Thu, 23 Sep 2021 04:05:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=GNSulH41k6CNGCmQxRveHbDDzr1clW/ordYhprr0Un4=; b=C+aNMwvyGZHmXLDsweZWMEg+vi7f5UYeKr5y3hpNc2UYgmXPeVXKf7hikgAOaCweJq inhWH5FJW9kNSjTGr6BUowMI3Ef8EKrlRHDS8Q8XbODP0BX1uGL4ZXGL6kK0CpHEJ7jY BtzsBNzL/CvWEED4QziEOoLncp4j1CpLis81djcPVKQfyjPTSFjnVgQ/yw+9vKsewbAV PAjb6Twv+go3OdUOhbWIAebGzgfDyf8euIGkMPGiYP2chhDz0bM0cZG65kjdCpA1xw8z RGsPh5nyFN21t16eO5Rms7h1il6sBnny1Wnq349vZS7pYwYdifxCVgqCddkKVFTo4EPr 5VaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=GNSulH41k6CNGCmQxRveHbDDzr1clW/ordYhprr0Un4=; b=y1rNvDNVqh9ffutx+u2BewRN6O1nPLIK8HCQ0WLyWY8r4nDJpma+e+KnLFKudlhCTP xP3NHJCJb3ydytyOCRBa+uTdrvu0vlwc7YTRdEg9IwP8C6V/AccBSy78w7cQ4B5JgHzv rllA4c/ProyLUoWqk4FmxT+RyltKQuBAT/3CCUQyuyBrs51WAa6A26s2s6rzGFsj2Wjh xCVjf9ELXbD0WO6T9ZCuzxy14l4njzyLLs79Yi9gCUu6figy6tbxOZe+Mzwrw5fTgLi4 DT0WULXX36tEOXfVgQ1UkPWUhrUu89sO3g1tqlvuiB0wXkN4yEmEVG6CgEcm0S2a3jhN YQpA== X-Gm-Message-State: AOAM532mD2jMCzAmEWMa39/e0eGu6TxIWyDXyHfLyJp+L7cF0eoG6LTu zrBnu5HKWWj4X5C1ZPgUWWjh/SqJ17Rnuw== X-Google-Smtp-Source: ABdhPJz+1rOyNMiBCWCdwUKqZwACRKuIEm9A2WmdqmtW/4KAgfk+ydnV0Zp52AR/efAgsT+ajP00pw== X-Received: by 2002:a63:7a45:: with SMTP id j5mr3612861pgn.369.1632395134835; Thu, 23 Sep 2021 04:05:34 -0700 (PDT) Received: from localhost.localdomain ([1.186.166.66]) by smtp.googlemail.com with ESMTPSA id w30sm9057607pjj.30.2021.09.23.04.05.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Sep 2021 04:05:34 -0700 (PDT) From: Vedant Paranjape To: libcamera-devel@lists.libcamera.org Date: Thu, 23 Sep 2021 16:35:18 +0530 Message-Id: <20210923110518.1556973-1-vedantparanjape160201@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1] test: gstreamer: Add a test for gstreamer multi stream X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nicolas.dufresne@collabora.com, Vedant Paranjape Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 Reviewed-by: Nicolas Dufresne --- 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. 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 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 +#include + +#include + +#include + +#include "libcamera/internal/source_paths.h" + +#include + +#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)