From patchwork Tue Sep 14 08:46:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vedant Paranjape X-Patchwork-Id: 13843 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 A7227BDC71 for ; Tue, 14 Sep 2021 08:46:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 167A969183; Tue, 14 Sep 2021 10:46:41 +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="kf1anRC+"; dkim-atps=neutral Received: from mail-pg1-x52c.google.com (mail-pg1-x52c.google.com [IPv6:2607:f8b0:4864:20::52c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2B30960249 for ; Tue, 14 Sep 2021 10:46:39 +0200 (CEST) Received: by mail-pg1-x52c.google.com with SMTP id k24so12058721pgh.8 for ; Tue, 14 Sep 2021 01:46:39 -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=VuQOHLUPC/m0muVZM2YA9YXlyq9USnu8hmK7IvajGjg=; b=kf1anRC+22u1E1p14StBViSOCxL3itnsictTsTAgNF6MMarzQYsZlzjbBTBTfFI9ze pjfbRevZBKG/lrLzP63A1NQMAiA0hrlKYeF1ygzkK3cPRxjH5wPeiOQTy9fcvOuibYaP Byoud+DI7NRVn7QpW2lLcq+57C/PDSfTJ1tfLCW67LEm68JQVzn0Y8Hw+yFky2TieV+x Z/MvmcSnzymY5sZGOxeh16kd1CTtp4w31RqbeDNryPrxg+V7tDp0CeExnbrKXfWud59J AMQkicQ3WYXR12H6m0pab2BYI+nPOKCKZntoj6NUhg6VccsDlspeDTAT05AsiVQ59sx3 PQdA== 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=VuQOHLUPC/m0muVZM2YA9YXlyq9USnu8hmK7IvajGjg=; b=xPGfmTt1lC+gukdNiouCZASROxgIOcL2PHGpsSlGKxfTaolpkPW+LyIs+gkF/UHLu3 vAdjC0MTT3Aa0JQ8MyXkOgHZSeSt35F4S5wN4ujTxey/N3f15fwX8o8x0oQLYPmN3XCM fNUCXFiYewXOIL3uePwsr08JIHi9uMXcb5GwXCpAfFswqUww8xEhyys+eg6cnK+/uFvK CAoLBCqnKb+n9dMFBUJhwaTo+bdVz0eQfQhzdnJ9MMOWVi5+KDo6rk7KG7d+l3vtI8T+ QjozuuL4ZGGzo2PjUscIvIghxmoM9gG+5IidIhDKAEN0X12mvqiWttospF3ShTAJFa1y r1vA== X-Gm-Message-State: AOAM531REJTWNzv0q87aM7S0Gllvp9OH0//dQvHsGtpom8MLjl5jaWWZ unayfk/Qj/F3iIIZrMTYjvaEp4h3Y6+jUcGH X-Google-Smtp-Source: ABdhPJzHhwbEwrudyLf3pMmnLkZmi0oSqhUu6ddnjZlqUVtCKNCuyOy91BnpBKf2WLg0ijt1pODX8w== X-Received: by 2002:a63:7807:: with SMTP id t7mr14554838pgc.474.1631609197327; Tue, 14 Sep 2021 01:46:37 -0700 (PDT) Received: from localhost.localdomain ([1.186.166.254]) by smtp.googlemail.com with ESMTPSA id a10sm9996018pfg.20.2021.09.14.01.46.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Sep 2021 01:46:37 -0700 (PDT) From: Vedant Paranjape To: libcamera-devel@lists.libcamera.org Date: Tue, 14 Sep 2021 14:16:22 +0530 Message-Id: <20210914084622.118939-1-vedantparanjape160201@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4] 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: 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 RPI pipeline. This was tested on a Raspberry Pi 4B+ Signed-off-by: Vedant Paranjape Reviewed-by: Paul Elder Tested-by: Paul Elder --- .../gstreamer/gstreamer_multi_stream_test.cpp | 138 ++++++++++++++++++ test/gstreamer/meson.build | 1 + 2 files changed, 139 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..aea9a1dcb211 --- /dev/null +++ b/test/gstreamer/gstreamer_multi_stream_test.cpp @@ -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 +#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; + } + + 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; + } + + if (createPipeline() != TestPass) + return TestFail; + + convert0_ = reinterpret_cast(g_steal_pointer(&convert0)); + convert1_ = reinterpret_cast(g_steal_pointer(&convert1)); + sink0_ = reinterpret_cast(g_steal_pointer(&sink0)); + sink1_ = reinterpret_cast(g_steal_pointer(&sink1)); + queue0_ = reinterpret_cast(g_steal_pointer(&queue0)); + queue1_ = reinterpret_cast(g_steal_pointer(&queue1)); + + 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) 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)