[{"id":19673,"web_url":"https://patchwork.libcamera.org/comment/19673/","msgid":"<c8954628-2464-d131-86e4-3309ff853552@ideasonboard.com>","date":"2021-09-14T10:23:00","subject":"Re: [libcamera-devel] [PATCH v4] test: gstreamer: Add a test for\n\tgstreamer multi stream","submitter":{"id":75,"url":"https://patchwork.libcamera.org/api/people/75/","name":"Jean-Michel Hautbois","email":"jeanmichel.hautbois@ideasonboard.com"},"content":"Hi Vedant,\n\nOn 14/09/2021 10:46, Vedant Paranjape wrote:\n> This patch adds a test to test if multi stream using libcamera's\n> gstreamer element works.\n\nA test to test :-) ?\nA proposal (I am not good at writing commit messages though so, please\nuse it with care :-)):\n\n> \n> Test will run only on devices that support multistream output, i.e.,\n> devices that use IPU3 and RPI pipeline. This was tested on a Raspberry\n> Pi 4B+\n> \n> Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> Tested-by: Paul Elder <paul.elder@ideasonboard.com>\n> ---\n>  .../gstreamer/gstreamer_multi_stream_test.cpp | 138 ++++++++++++++++++\n>  test/gstreamer/meson.build                    |   1 +\n>  2 files changed, 139 insertions(+)\n>  create mode 100644 test/gstreamer/gstreamer_multi_stream_test.cpp\n> \n> diff --git a/test/gstreamer/gstreamer_multi_stream_test.cpp b/test/gstreamer/gstreamer_multi_stream_test.cpp\n> new file mode 100644\n> index 000000000000..aea9a1dcb211\n> --- /dev/null\n> +++ b/test/gstreamer/gstreamer_multi_stream_test.cpp\n> @@ -0,0 +1,138 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2021, Vedant Paranjape\n> + *\n> + * gstreamer_multi_stream_test.cpp - GStreamer multi stream capture test\n> + */\n> +\n> +#include <iostream>\n> +#include <unistd.h>\n> +\n> +#include <libcamera/base/utils.h>\n> +\n> +#include <libcamera/libcamera.h>\n> +\n> +#include \"libcamera/internal/source_paths.h\"\n> +\n> +#include <gst/gst.h>\n> +\n> +#include \"gstreamer_test.h\"\n> +#include \"test.h\"\n> +\n> +using namespace std;\n> +\n> +class GstreamerMultiStreamTest : public GstreamerTest, public Test\n> +{\n> +public:\n> +\tGstreamerMultiStreamTest()\n> +\t\t: GstreamerTest()\n> +\t{\n> +\t}\n> +\n> +protected:\n> +\tint init() override\n> +\t{\n> +\t\tif (status_ != TestPass)\n> +\t\t\treturn status_;\n> +\n> +\t\t/* Check if platform support multistream output */\n> +\t\tlibcamera::CameraManager cm;\n> +\t\tcm.start();\n> +\t\tbool cameraFound = false;\n> +\t\tfor (auto &camera : cm.cameras()) {\n> +\t\t\tif (camera->streams().size() > 1) {\n> +\t\t\t\tcameraName = camera->id();\n> +\t\t\t\tcameraFound = true;\n> +\t\t\t\tcm.stop();\n> +\t\t\t\tbreak;\n> +\t\t\t}\n> +\t\t}\n> +\n> +\t\tif (!cameraFound) {\n> +\t\t\tcm.stop();\n> +\t\t\treturn TestSkip;\n> +\t\t}\n> +\n> +\t\tg_autoptr(GstElement) convert0 = gst_element_factory_make(\"videoconvert\", \"convert0\");\n> +\t\tg_autoptr(GstElement) convert1 = gst_element_factory_make(\"videoconvert\", \"convert1\");\n\nWhy do you need a convert element ? AFAIK you are outputting into a\nfakesink it should not be an issue ?\n\n> +\t\tg_autoptr(GstElement) sink0 = gst_element_factory_make(\"fakesink\", \"sink0\");\n> +\t\tg_autoptr(GstElement) sink1 = gst_element_factory_make(\"fakesink\", \"sink1\");\n> +\t\tg_autoptr(GstElement) queue0 = gst_element_factory_make(\"queue\", \"queue0\");\n> +\t\tg_autoptr(GstElement) queue1 = gst_element_factory_make(\"queue\", \"queue1\");\n> +\t\tg_object_ref_sink(convert0);\n> +\t\tg_object_ref_sink(convert1);\n> +\t\tg_object_ref_sink(sink0);\n> +\t\tg_object_ref_sink(sink1);\n> +\t\tg_object_ref_sink(queue0);\n> +\t\tg_object_ref_sink(queue1);\n\nI don't really like that, why can't you use\ngst_parse_bin_from_description() for instance ?\nThat way you would get a bin you could link to libcamerasrc.\n\nNote: it is a long time since I really use GStreamer so I may not be\nup-to-date, Nicolas may a different comment, and he would be the one to\nfollow ;-).\n\n> +\n> +\t\tif (!convert0 || !convert1 || !sink0 || !sink1 || !queue0 || !queue1) {\n> +\t\t\tg_printerr(\"Not all elements could be created. %p.%p.%p.%p.%p.%p\\n\",\n> +\t\t\t\t   convert0, convert1, sink0, sink1, queue0, queue1);\n> +\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (createPipeline() != TestPass)\n> +\t\t\treturn TestFail;\n> +\n> +\t\tconvert0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&convert0));\n> +\t\tconvert1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&convert1));\n> +\t\tsink0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&sink0));\n> +\t\tsink1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&sink1));\n> +\t\tqueue0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&queue0));\n> +\t\tqueue1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&queue1));\n> +\n> +\t\treturn TestPass;\n> +\t}\n> +\n> +\tint run() override\n> +\t{\n> +\t\tg_object_set(libcameraSrc_, \"camera-name\", cameraName.c_str(), NULL);\n> +\n> +\t\t/* Build the pipeline */\n> +\t\tgst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, queue0_, queue1_,\n> +\t\t\t\t convert0_, convert1_, sink0_, sink1_, NULL);\n> +\t\tif (gst_element_link_many(queue0_, convert0_, sink0_, NULL) != TRUE ||\n> +\t\t    gst_element_link_many(queue1_, convert1_, sink1_, NULL) != TRUE) {\n> +\t\t\tg_printerr(\"Elements could not be linked.\\n\");\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tg_autoptr(GstPad) src_pad = gst_element_get_static_pad(libcameraSrc_, \"src\");\n> +\t\tg_autoptr(GstPad) request_pad = gst_element_get_request_pad(libcameraSrc_, \"src_%u\");\n> +\t\tGstPad *queue0_sink_pad = gst_element_get_static_pad(queue0_, \"sink\");\n> +\t\tGstPad *queue1_sink_pad = gst_element_get_static_pad(queue1_, \"sink\");\n> +\n> +\t\tif (gst_pad_link(src_pad, queue0_sink_pad) != GST_PAD_LINK_OK\n> +\t\t\t|| gst_pad_link(request_pad, queue1_sink_pad) != GST_PAD_LINK_OK) {\n> +\t\t\tif (queue0_sink_pad)\n> +\t\t\t\tgst_object_unref(queue0_sink_pad);\n> +\t\t\tif (queue1_sink_pad)\n> +\t\t\t\tgst_object_unref(queue1_sink_pad);\n> +\t\t\tg_printerr(\"Pads could not be linked.\\n\");\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\t\tgst_object_unref(queue0_sink_pad);\n> +\t\tgst_object_unref(queue1_sink_pad);\n> +\n> +\t\tif (startPipeline() != TestPass)\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (processEvent() != TestPass)\n> +\t\t\treturn TestFail;\n> +\n> +\t\treturn TestPass;\n> +\t}\n> +\n> +private:\n> +\tstd::string cameraName;\n> +\tGstElement *convert0_;\n> +\tGstElement *convert1_;\n> +\tGstElement *sink0_;\n> +\tGstElement *sink1_;\n> +\tGstElement *queue0_;\n> +\tGstElement *queue1_;\n> +};\n> +\n> +TEST_REGISTER(GstreamerMultiStreamTest)\n> diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> index aca53b920365..13652e87d05c 100644\n> --- a/test/gstreamer/meson.build\n> +++ b/test/gstreamer/meson.build\n> @@ -6,6 +6,7 @@ endif\n>  \n>  gstreamer_tests = [\n>      ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> +    ['multi_stream_test',   'gstreamer_multi_stream_test.cpp'],\n>  ]\n>  gstreamer_dep = dependency('gstreamer-1.0', required: true)\n>  \n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 4FCCFBDB1D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 14 Sep 2021 10:23:04 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C76866024A;\n\tTue, 14 Sep 2021 12:23:03 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7DA2860132\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 14 Sep 2021 12:23:02 +0200 (CEST)","from tatooine.ideasonboard.com (unknown\n\t[IPv6:2a01:e0a:169:7140:d0a7:2575:a724:b30a])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 17E202A5;\n\tTue, 14 Sep 2021 12:23:02 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"aUigddaR\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1631614982;\n\tbh=Rj6Bi1YfsrSkAnnO/Z609iPwItQ0ljbhsFYbnyHGG4c=;\n\th=Subject:To:References:From:Date:In-Reply-To:From;\n\tb=aUigddaRIk+qGTJnGqNTgSo1vvZGK6JOUaEvBtQ/Dy1K1Cvaj3WFBViWGfWEOblSR\n\tMGtSYO+hreqgWKDJ96AASyw4mZS7PF1u9r91dnpJ6hP1LdjZsZn69mCipoRo+8OLqI\n\tuXXZcXhRACabu2bJ+pF2LfW92K48ZURdsGz6KXnk=","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20210914084622.118939-1-vedantparanjape160201@gmail.com>","From":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<c8954628-2464-d131-86e4-3309ff853552@ideasonboard.com>","Date":"Tue, 14 Sep 2021 12:23:00 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.13.0","MIME-Version":"1.0","In-Reply-To":"<20210914084622.118939-1-vedantparanjape160201@gmail.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v4] test: gstreamer: Add a test for\n\tgstreamer multi stream","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19674,"web_url":"https://patchwork.libcamera.org/comment/19674/","msgid":"<24f66a76-4581-20fa-7157-32d14480cb95@ideasonboard.com>","date":"2021-09-14T10:24:37","subject":"Re: [libcamera-devel] [PATCH v4] test: gstreamer: Add a test for\n\tgstreamer multi stream","submitter":{"id":75,"url":"https://patchwork.libcamera.org/api/people/75/","name":"Jean-Michel Hautbois","email":"jeanmichel.hautbois@ideasonboard.com"},"content":"On 14/09/2021 12:23, Jean-Michel Hautbois wrote:\n> Hi Vedant,\n> \n> On 14/09/2021 10:46, Vedant Paranjape wrote:\n>> This patch adds a test to test if multi stream using libcamera's\n>> gstreamer element works.\n> \n> A test to test :-) ?\n> A proposal (I am not good at writing commit messages though so, please\n> use it with care :-)):\n\nI obviously forgot to paste it... :-/ and now I lost it...\nBasically, introduce the fact we are not testing it and just say what\nthis test does (outputs two streams in fakesink if multi-stream is\nsupported by the device).\n\n> \n>>\n>> Test will run only on devices that support multistream output, i.e.,\n>> devices that use IPU3 and RPI pipeline. This was tested on a Raspberry\n>> Pi 4B+\n>>\n>> Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n>> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n>> Tested-by: Paul Elder <paul.elder@ideasonboard.com>\n>> ---\n>>  .../gstreamer/gstreamer_multi_stream_test.cpp | 138 ++++++++++++++++++\n>>  test/gstreamer/meson.build                    |   1 +\n>>  2 files changed, 139 insertions(+)\n>>  create mode 100644 test/gstreamer/gstreamer_multi_stream_test.cpp\n>>\n>> diff --git a/test/gstreamer/gstreamer_multi_stream_test.cpp b/test/gstreamer/gstreamer_multi_stream_test.cpp\n>> new file mode 100644\n>> index 000000000000..aea9a1dcb211\n>> --- /dev/null\n>> +++ b/test/gstreamer/gstreamer_multi_stream_test.cpp\n>> @@ -0,0 +1,138 @@\n>> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n>> +/*\n>> + * Copyright (C) 2021, Vedant Paranjape\n>> + *\n>> + * gstreamer_multi_stream_test.cpp - GStreamer multi stream capture test\n>> + */\n>> +\n>> +#include <iostream>\n>> +#include <unistd.h>\n>> +\n>> +#include <libcamera/base/utils.h>\n>> +\n>> +#include <libcamera/libcamera.h>\n>> +\n>> +#include \"libcamera/internal/source_paths.h\"\n>> +\n>> +#include <gst/gst.h>\n>> +\n>> +#include \"gstreamer_test.h\"\n>> +#include \"test.h\"\n>> +\n>> +using namespace std;\n>> +\n>> +class GstreamerMultiStreamTest : public GstreamerTest, public Test\n>> +{\n>> +public:\n>> +\tGstreamerMultiStreamTest()\n>> +\t\t: GstreamerTest()\n>> +\t{\n>> +\t}\n>> +\n>> +protected:\n>> +\tint init() override\n>> +\t{\n>> +\t\tif (status_ != TestPass)\n>> +\t\t\treturn status_;\n>> +\n>> +\t\t/* Check if platform support multistream output */\n>> +\t\tlibcamera::CameraManager cm;\n>> +\t\tcm.start();\n>> +\t\tbool cameraFound = false;\n>> +\t\tfor (auto &camera : cm.cameras()) {\n>> +\t\t\tif (camera->streams().size() > 1) {\n>> +\t\t\t\tcameraName = camera->id();\n>> +\t\t\t\tcameraFound = true;\n>> +\t\t\t\tcm.stop();\n>> +\t\t\t\tbreak;\n>> +\t\t\t}\n>> +\t\t}\n>> +\n>> +\t\tif (!cameraFound) {\n>> +\t\t\tcm.stop();\n>> +\t\t\treturn TestSkip;\n>> +\t\t}\n>> +\n>> +\t\tg_autoptr(GstElement) convert0 = gst_element_factory_make(\"videoconvert\", \"convert0\");\n>> +\t\tg_autoptr(GstElement) convert1 = gst_element_factory_make(\"videoconvert\", \"convert1\");\n> \n> Why do you need a convert element ? AFAIK you are outputting into a\n> fakesink it should not be an issue ?\n> \n>> +\t\tg_autoptr(GstElement) sink0 = gst_element_factory_make(\"fakesink\", \"sink0\");\n>> +\t\tg_autoptr(GstElement) sink1 = gst_element_factory_make(\"fakesink\", \"sink1\");\n>> +\t\tg_autoptr(GstElement) queue0 = gst_element_factory_make(\"queue\", \"queue0\");\n>> +\t\tg_autoptr(GstElement) queue1 = gst_element_factory_make(\"queue\", \"queue1\");\n>> +\t\tg_object_ref_sink(convert0);\n>> +\t\tg_object_ref_sink(convert1);\n>> +\t\tg_object_ref_sink(sink0);\n>> +\t\tg_object_ref_sink(sink1);\n>> +\t\tg_object_ref_sink(queue0);\n>> +\t\tg_object_ref_sink(queue1);\n> \n> I don't really like that, why can't you use\n> gst_parse_bin_from_description() for instance ?\n> That way you would get a bin you could link to libcamerasrc.\n> \n> Note: it is a long time since I really use GStreamer so I may not be\n> up-to-date, Nicolas may a different comment, and he would be the one to\n> follow ;-).\n> \n>> +\n>> +\t\tif (!convert0 || !convert1 || !sink0 || !sink1 || !queue0 || !queue1) {\n>> +\t\t\tg_printerr(\"Not all elements could be created. %p.%p.%p.%p.%p.%p\\n\",\n>> +\t\t\t\t   convert0, convert1, sink0, sink1, queue0, queue1);\n>> +\n>> +\t\t\treturn TestFail;\n>> +\t\t}\n>> +\n>> +\t\tif (createPipeline() != TestPass)\n>> +\t\t\treturn TestFail;\n>> +\n>> +\t\tconvert0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&convert0));\n>> +\t\tconvert1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&convert1));\n>> +\t\tsink0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&sink0));\n>> +\t\tsink1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&sink1));\n>> +\t\tqueue0_ = reinterpret_cast<GstElement *>(g_steal_pointer(&queue0));\n>> +\t\tqueue1_ = reinterpret_cast<GstElement *>(g_steal_pointer(&queue1));\n>> +\n>> +\t\treturn TestPass;\n>> +\t}\n>> +\n>> +\tint run() override\n>> +\t{\n>> +\t\tg_object_set(libcameraSrc_, \"camera-name\", cameraName.c_str(), NULL);\n>> +\n>> +\t\t/* Build the pipeline */\n>> +\t\tgst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, queue0_, queue1_,\n>> +\t\t\t\t convert0_, convert1_, sink0_, sink1_, NULL);\n>> +\t\tif (gst_element_link_many(queue0_, convert0_, sink0_, NULL) != TRUE ||\n>> +\t\t    gst_element_link_many(queue1_, convert1_, sink1_, NULL) != TRUE) {\n>> +\t\t\tg_printerr(\"Elements could not be linked.\\n\");\n>> +\t\t\treturn TestFail;\n>> +\t\t}\n>> +\n>> +\t\tg_autoptr(GstPad) src_pad = gst_element_get_static_pad(libcameraSrc_, \"src\");\n>> +\t\tg_autoptr(GstPad) request_pad = gst_element_get_request_pad(libcameraSrc_, \"src_%u\");\n>> +\t\tGstPad *queue0_sink_pad = gst_element_get_static_pad(queue0_, \"sink\");\n>> +\t\tGstPad *queue1_sink_pad = gst_element_get_static_pad(queue1_, \"sink\");\n>> +\n>> +\t\tif (gst_pad_link(src_pad, queue0_sink_pad) != GST_PAD_LINK_OK\n>> +\t\t\t|| gst_pad_link(request_pad, queue1_sink_pad) != GST_PAD_LINK_OK) {\n>> +\t\t\tif (queue0_sink_pad)\n>> +\t\t\t\tgst_object_unref(queue0_sink_pad);\n>> +\t\t\tif (queue1_sink_pad)\n>> +\t\t\t\tgst_object_unref(queue1_sink_pad);\n>> +\t\t\tg_printerr(\"Pads could not be linked.\\n\");\n>> +\t\t\treturn TestFail;\n>> +\t\t}\n>> +\t\tgst_object_unref(queue0_sink_pad);\n>> +\t\tgst_object_unref(queue1_sink_pad);\n>> +\n>> +\t\tif (startPipeline() != TestPass)\n>> +\t\t\treturn TestFail;\n>> +\n>> +\t\tif (processEvent() != TestPass)\n>> +\t\t\treturn TestFail;\n>> +\n>> +\t\treturn TestPass;\n>> +\t}\n>> +\n>> +private:\n>> +\tstd::string cameraName;\n>> +\tGstElement *convert0_;\n>> +\tGstElement *convert1_;\n>> +\tGstElement *sink0_;\n>> +\tGstElement *sink1_;\n>> +\tGstElement *queue0_;\n>> +\tGstElement *queue1_;\n>> +};\n>> +\n>> +TEST_REGISTER(GstreamerMultiStreamTest)\n>> diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n>> index aca53b920365..13652e87d05c 100644\n>> --- a/test/gstreamer/meson.build\n>> +++ b/test/gstreamer/meson.build\n>> @@ -6,6 +6,7 @@ endif\n>>  \n>>  gstreamer_tests = [\n>>      ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n>> +    ['multi_stream_test',   'gstreamer_multi_stream_test.cpp'],\n>>  ]\n>>  gstreamer_dep = dependency('gstreamer-1.0', required: true)\n>>  \n>>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 7D0E3BDB1D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 14 Sep 2021 10:24:42 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4C9246918A;\n\tTue, 14 Sep 2021 12:24:42 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4171D60132\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 14 Sep 2021 12:24:40 +0200 (CEST)","from tatooine.ideasonboard.com (unknown\n\t[IPv6:2a01:e0a:169:7140:d0a7:2575:a724:b30a])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EB5402A5;\n\tTue, 14 Sep 2021 12:24:39 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"C8XCwLh4\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1631615080;\n\tbh=iw0fAeJNsA+vPhwXc1aOVp7L2z9lTTsOHsfcH1SFuaU=;\n\th=Subject:From:To:References:Date:In-Reply-To:From;\n\tb=C8XCwLh4mORCd3U5dabbUJ57RfTCCw5qLRlY+5gnRw5BnbdmnVKLfVy8oCgfjXy77\n\thWuM2yaRiVJZvw7Yl4JY7SAWYfP8Oh8pGz6uIeGZvkW5sEUp6WUIwatBMibOX/5yU1\n\trDK5i1kSQ2DzZ1Nf9qwED0Wha5rU2TTCbaUBVwF8=","From":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20210914084622.118939-1-vedantparanjape160201@gmail.com>\n\t<c8954628-2464-d131-86e4-3309ff853552@ideasonboard.com>","Message-ID":"<24f66a76-4581-20fa-7157-32d14480cb95@ideasonboard.com>","Date":"Tue, 14 Sep 2021 12:24:37 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.13.0","MIME-Version":"1.0","In-Reply-To":"<c8954628-2464-d131-86e4-3309ff853552@ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v4] test: gstreamer: Add a test for\n\tgstreamer multi stream","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19677,"web_url":"https://patchwork.libcamera.org/comment/19677/","msgid":"<CACGrz-PTJuRe3ent+C=0uTKWeSSev6hgWRVdpp7O5YT=y0fMjg@mail.gmail.com>","date":"2021-09-14T10:39:27","subject":"Re: [libcamera-devel] [PATCH v4] test: gstreamer: Add a test for\n\tgstreamer multi stream","submitter":{"id":85,"url":"https://patchwork.libcamera.org/api/people/85/","name":"Vedant Paranjape","email":"vedantparanjape160201@gmail.com"},"content":"Hi Jean-Michel\nThanks for your review.\n\n\nOn Tue, Sep 14, 2021 at 3:53 PM Jean-Michel Hautbois <\njeanmichel.hautbois@ideasonboard.com> wrote:\n\n> Hi Vedant,\n>\n> On 14/09/2021 10:46, Vedant Paranjape wrote:\n> > This patch adds a test to test if multi stream using libcamera's\n> > gstreamer element works.\n>\n> A test to test :-) ?\n> A proposal (I am not good at writing commit messages though so, please\n> use it with care :-)):\n>\n\nhaha, even the single stream test had same commit message, and it went in,\nso didn't think about anything different.\n\n>\n> > Test will run only on devices that support multistream output, i.e.,\n> > devices that use IPU3 and RPI pipeline. This was tested on a Raspberry\n> > Pi 4B+\n> >\n> > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > Tested-by: Paul Elder <paul.elder@ideasonboard.com>\n> > ---\n> >  .../gstreamer/gstreamer_multi_stream_test.cpp | 138 ++++++++++++++++++\n> >  test/gstreamer/meson.build                    |   1 +\n> >  2 files changed, 139 insertions(+)\n> >  create mode 100644 test/gstreamer/gstreamer_multi_stream_test.cpp\n> >\n> > diff --git a/test/gstreamer/gstreamer_multi_stream_test.cpp\n> b/test/gstreamer/gstreamer_multi_stream_test.cpp\n> > new file mode 100644\n> > index 000000000000..aea9a1dcb211\n> > --- /dev/null\n> > +++ b/test/gstreamer/gstreamer_multi_stream_test.cpp\n> > @@ -0,0 +1,138 @@\n> > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > +/*\n> > + * Copyright (C) 2021, Vedant Paranjape\n> > + *\n> > + * gstreamer_multi_stream_test.cpp - GStreamer multi stream capture test\n> > + */\n> > +\n> > +#include <iostream>\n> > +#include <unistd.h>\n> > +\n> > +#include <libcamera/base/utils.h>\n> > +\n> > +#include <libcamera/libcamera.h>\n> > +\n> > +#include \"libcamera/internal/source_paths.h\"\n> > +\n> > +#include <gst/gst.h>\n> > +\n> > +#include \"gstreamer_test.h\"\n> > +#include \"test.h\"\n> > +\n> > +using namespace std;\n> > +\n> > +class GstreamerMultiStreamTest : public GstreamerTest, public Test\n> > +{\n> > +public:\n> > +     GstreamerMultiStreamTest()\n> > +             : GstreamerTest()\n> > +     {\n> > +     }\n> > +\n> > +protected:\n> > +     int init() override\n> > +     {\n> > +             if (status_ != TestPass)\n> > +                     return status_;\n> > +\n> > +             /* Check if platform support multistream output */\n> > +             libcamera::CameraManager cm;\n> > +             cm.start();\n> > +             bool cameraFound = false;\n> > +             for (auto &camera : cm.cameras()) {\n> > +                     if (camera->streams().size() > 1) {\n> > +                             cameraName = camera->id();\n> > +                             cameraFound = true;\n> > +                             cm.stop();\n> > +                             break;\n> > +                     }\n> > +             }\n> > +\n> > +             if (!cameraFound) {\n> > +                     cm.stop();\n> > +                     return TestSkip;\n> > +             }\n> > +\n> > +             g_autoptr(GstElement) convert0 =\n> gst_element_factory_make(\"videoconvert\", \"convert0\");\n> > +             g_autoptr(GstElement) convert1 =\n> gst_element_factory_make(\"videoconvert\", \"convert1\");\n>\n> Why do you need a convert element ? AFAIK you are outputting into a\n> fakesink it should not be an issue ?\n>\n\nThis is an artifact from the old code which used autovideosink but was\nchanged to fakesink. I'll test if removing it works, I'd want to use stats\nproperty in future, I assume it won't work if I remove videoconvert.\n\n> +             g_autoptr(GstElement) sink0 =\n> gst_element_factory_make(\"fakesink\", \"sink0\");\n> > +             g_autoptr(GstElement) sink1 =\n> gst_element_factory_make(\"fakesink\", \"sink1\");\n> > +             g_autoptr(GstElement) queue0 =\n> gst_element_factory_make(\"queue\", \"queue0\");\n> > +             g_autoptr(GstElement) queue1 =\n> gst_element_factory_make(\"queue\", \"queue1\");\n> > +             g_object_ref_sink(convert0);\n> > +             g_object_ref_sink(convert1);\n> > +             g_object_ref_sink(sink0);\n> > +             g_object_ref_sink(sink1);\n> > +             g_object_ref_sink(queue0);\n> > +             g_object_ref_sink(queue1);\n>\n> I don't really like that, why can't you use\n> gst_parse_bin_from_description() for instance ?\n> That way you would get a bin you could link to libcamerasrc.\n>\n\nI think the answer to that lies in run() function, I'm doing using request\npads so, that won't be possible if I just use a bin. I maybe wrong, I'll\nwait for Nicolas's comment as you said.\n\nNote: it is a long time since I really use GStreamer so I may not be\n> up-to-date, Nicolas may a different comment, and he would be the one to\n> follow ;-).\n>\n> > +\n> > +             if (!convert0 || !convert1 || !sink0 || !sink1 || !queue0\n> || !queue1) {\n> > +                     g_printerr(\"Not all elements could be created.\n> %p.%p.%p.%p.%p.%p\\n\",\n> > +                                convert0, convert1, sink0, sink1,\n> queue0, queue1);\n> > +\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             if (createPipeline() != TestPass)\n> > +                     return TestFail;\n> > +\n> > +             convert0_ = reinterpret_cast<GstElement\n> *>(g_steal_pointer(&convert0));\n> > +             convert1_ = reinterpret_cast<GstElement\n> *>(g_steal_pointer(&convert1));\n> > +             sink0_ = reinterpret_cast<GstElement\n> *>(g_steal_pointer(&sink0));\n> > +             sink1_ = reinterpret_cast<GstElement\n> *>(g_steal_pointer(&sink1));\n> > +             queue0_ = reinterpret_cast<GstElement\n> *>(g_steal_pointer(&queue0));\n> > +             queue1_ = reinterpret_cast<GstElement\n> *>(g_steal_pointer(&queue1));\n> > +\n> > +             return TestPass;\n> > +     }\n> > +\n> > +     int run() override\n> > +     {\n> > +             g_object_set(libcameraSrc_, \"camera-name\",\n> cameraName.c_str(), NULL);\n> > +\n> > +             /* Build the pipeline */\n> > +             gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,\n> queue0_, queue1_,\n> > +                              convert0_, convert1_, sink0_, sink1_,\n> NULL);\n> > +             if (gst_element_link_many(queue0_, convert0_, sink0_,\n> NULL) != TRUE ||\n> > +                 gst_element_link_many(queue1_, convert1_, sink1_,\n> NULL) != TRUE) {\n> > +                     g_printerr(\"Elements could not be linked.\\n\");\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             g_autoptr(GstPad) src_pad =\n> gst_element_get_static_pad(libcameraSrc_, \"src\");\n> > +             g_autoptr(GstPad) request_pad =\n> gst_element_get_request_pad(libcameraSrc_, \"src_%u\");\n> > +             GstPad *queue0_sink_pad =\n> gst_element_get_static_pad(queue0_, \"sink\");\n> > +             GstPad *queue1_sink_pad =\n> gst_element_get_static_pad(queue1_, \"sink\");\n> > +\n> > +             if (gst_pad_link(src_pad, queue0_sink_pad) !=\n> GST_PAD_LINK_OK\n> > +                     || gst_pad_link(request_pad, queue1_sink_pad) !=\n> GST_PAD_LINK_OK) {\n> > +                     if (queue0_sink_pad)\n> > +                             gst_object_unref(queue0_sink_pad);\n> > +                     if (queue1_sink_pad)\n> > +                             gst_object_unref(queue1_sink_pad);\n> > +                     g_printerr(\"Pads could not be linked.\\n\");\n> > +                     return TestFail;\n> > +             }\n> > +             gst_object_unref(queue0_sink_pad);\n> > +             gst_object_unref(queue1_sink_pad);\n> > +\n> > +             if (startPipeline() != TestPass)\n> > +                     return TestFail;\n> > +\n> > +             if (processEvent() != TestPass)\n> > +                     return TestFail;\n> > +\n> > +             return TestPass;\n> > +     }\n> > +\n> > +private:\n> > +     std::string cameraName;\n> > +     GstElement *convert0_;\n> > +     GstElement *convert1_;\n> > +     GstElement *sink0_;\n> > +     GstElement *sink1_;\n> > +     GstElement *queue0_;\n> > +     GstElement *queue1_;\n> > +};\n> > +\n> > +TEST_REGISTER(GstreamerMultiStreamTest)\n> > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > index aca53b920365..13652e87d05c 100644\n> > --- a/test/gstreamer/meson.build\n> > +++ b/test/gstreamer/meson.build\n> > @@ -6,6 +6,7 @@ endif\n> >\n> >  gstreamer_tests = [\n> >      ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> > +    ['multi_stream_test',   'gstreamer_multi_stream_test.cpp'],\n> >  ]\n> >  gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> >\n> >\n>\n\nRegards,\n*Vedant Paranjape*","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id ED0E9BDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 14 Sep 2021 10:39:41 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 32AF36918C;\n\tTue, 14 Sep 2021 12:39:41 +0200 (CEST)","from mail-yb1-xb34.google.com (mail-yb1-xb34.google.com\n\t[IPv6:2607:f8b0:4864:20::b34])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2740760249\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 14 Sep 2021 12:39:40 +0200 (CEST)","by mail-yb1-xb34.google.com with SMTP id c6so27106417ybm.10\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 14 Sep 2021 03:39:40 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"ll1BL62O\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=e3TaiW6D0I+f/W78boDe7/4aR1Aoj+TqnRRDP6dMbfM=;\n\tb=ll1BL62OuswCInKMI90CxiJ+lr59b+2CS2xqJLLZdHdIVfwvoOT3N9TFc/cDoOB9yD\n\t7IIYh3aF2xd3p+zx/0EHjxsXsgYbkJ3AGWDM+SYhGl3X3GPFFB6WXkl7g6uxy/RtZddX\n\tWZt7EjIlyE7ixwikkSx0nZy6Il6gA0km5QcIhoeAvossdrYlys7ip2D+tX1h8fLUyEYT\n\tIWG8YN7uhMcXScpBpZEKjkf0FZoh2JEv4q/qfEN6Rxmqo06OpocUY9ln67hbo5k97TLD\n\tIEuQs+bQ8TVtwDrV/NoE+yesrnWjQlw+2qxGY2nenuWiXyqvbs1hLgQhNFJtRYAPAMLd\n\tGU/w==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=e3TaiW6D0I+f/W78boDe7/4aR1Aoj+TqnRRDP6dMbfM=;\n\tb=dm2kYC9VUqTl6/0kYhsPbz3qs7HO1PpA4Wo+J/c70xoQS2diqnzb5alHIIGyBHF0lV\n\tNSqx2MFFZgNnuorlVjl9SEafgDpReCzAeuqULMUxuK8mmIkYjKcSzjlvIRPTK8B03opB\n\t2958ju00AZU/2h0jTDQVAGeZ3QGiKtK6ql480v2XaV6HDpyrlUf3LLL6eZg3bCqSeoM/\n\tYBOgHwYNFxHYMJClJDFXqBvzhN/uW/n02Rx+gNbFL2RfXvDukr1EuyIwvIS3h2NdnmXA\n\tqD4ljeM9dHuHuKVgz0CO5uq805hPPwvlceIPddHuhqOfO/BbhlFFijTnTXPnD8xL1Mpv\n\tUBvA==","X-Gm-Message-State":"AOAM533iALVrmexJyA/Zk08Mw96NATne+5hBBAZfBCG8D0j/XuwDAC+X\n\tgmVXSOzNtNLG21ymI/2N4hKgOaYlrhpoY6udZGLfJN+gcFD4DA==","X-Google-Smtp-Source":"ABdhPJxORN2dQMBgWIYrcpJZ2LdAsjJNac6L3MoPRKHQu/gvKN1tpCd+uZMe0kWzfxhlLmGHO5WNC7qsfsBhIZ8NsOE=","X-Received":"by 2002:a25:5095:: with SMTP id\n\te143mr22319156ybb.213.1631615978945; \n\tTue, 14 Sep 2021 03:39:38 -0700 (PDT)","MIME-Version":"1.0","References":"<20210914084622.118939-1-vedantparanjape160201@gmail.com>\n\t<c8954628-2464-d131-86e4-3309ff853552@ideasonboard.com>","In-Reply-To":"<c8954628-2464-d131-86e4-3309ff853552@ideasonboard.com>","From":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Date":"Tue, 14 Sep 2021 16:09:27 +0530","Message-ID":"<CACGrz-PTJuRe3ent+C=0uTKWeSSev6hgWRVdpp7O5YT=y0fMjg@mail.gmail.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"000000000000d5c0eb05cbf232a1\"","Subject":"Re: [libcamera-devel] [PATCH v4] test: gstreamer: Add a test for\n\tgstreamer multi stream","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19678,"web_url":"https://patchwork.libcamera.org/comment/19678/","msgid":"<CACGrz-P04wvPRBkUxOUhfD0_Hw=Ynj7jRFks93BumJDhEefxDA@mail.gmail.com>","date":"2021-09-14T10:42:35","subject":"Re: [libcamera-devel] [PATCH v4] test: gstreamer: Add a test for\n\tgstreamer multi stream","submitter":{"id":85,"url":"https://patchwork.libcamera.org/api/people/85/","name":"Vedant Paranjape","email":"vedantparanjape160201@gmail.com"},"content":"On Tue, Sep 14, 2021 at 4:09 PM Vedant Paranjape <\nvedantparanjape160201@gmail.com> wrote:\n\n> Hi Jean-Michel\n> Thanks for your review.\n>\n>\n> On Tue, Sep 14, 2021 at 3:53 PM Jean-Michel Hautbois <\n> jeanmichel.hautbois@ideasonboard.com> wrote:\n>\n>> Hi Vedant,\n>>\n>> On 14/09/2021 10:46, Vedant Paranjape wrote:\n>> > This patch adds a test to test if multi stream using libcamera's\n>> > gstreamer element works.\n>>\n>> A test to test :-) ?\n>> A proposal (I am not good at writing commit messages though so, please\n>> use it with care :-)):\n>>\n>\n> haha, even the single stream test had same commit message, and it went in,\n> so didn't think about anything different.\n>\n> >\n>> > Test will run only on devices that support multistream output, i.e.,\n>> > devices that use IPU3 and RPI pipeline. This was tested on a Raspberry\n>> > Pi 4B+\n>> >\n>> > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n>> > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n>> > Tested-by: Paul Elder <paul.elder@ideasonboard.com>\n>> > ---\n>> >  .../gstreamer/gstreamer_multi_stream_test.cpp | 138 ++++++++++++++++++\n>> >  test/gstreamer/meson.build                    |   1 +\n>> >  2 files changed, 139 insertions(+)\n>> >  create mode 100644 test/gstreamer/gstreamer_multi_stream_test.cpp\n>> >\n>> > diff --git a/test/gstreamer/gstreamer_multi_stream_test.cpp\n>> b/test/gstreamer/gstreamer_multi_stream_test.cpp\n>> > new file mode 100644\n>> > index 000000000000..aea9a1dcb211\n>> > --- /dev/null\n>> > +++ b/test/gstreamer/gstreamer_multi_stream_test.cpp\n>> > @@ -0,0 +1,138 @@\n>> > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n>> > +/*\n>> > + * Copyright (C) 2021, Vedant Paranjape\n>> > + *\n>> > + * gstreamer_multi_stream_test.cpp - GStreamer multi stream capture\n>> test\n>> > + */\n>> > +\n>> > +#include <iostream>\n>> > +#include <unistd.h>\n>> > +\n>> > +#include <libcamera/base/utils.h>\n>> > +\n>> > +#include <libcamera/libcamera.h>\n>> > +\n>> > +#include \"libcamera/internal/source_paths.h\"\n>> > +\n>> > +#include <gst/gst.h>\n>> > +\n>> > +#include \"gstreamer_test.h\"\n>> > +#include \"test.h\"\n>> > +\n>> > +using namespace std;\n>> > +\n>> > +class GstreamerMultiStreamTest : public GstreamerTest, public Test\n>> > +{\n>> > +public:\n>> > +     GstreamerMultiStreamTest()\n>> > +             : GstreamerTest()\n>> > +     {\n>> > +     }\n>> > +\n>> > +protected:\n>> > +     int init() override\n>> > +     {\n>> > +             if (status_ != TestPass)\n>> > +                     return status_;\n>> > +\n>> > +             /* Check if platform support multistream output */\n>> > +             libcamera::CameraManager cm;\n>> > +             cm.start();\n>> > +             bool cameraFound = false;\n>> > +             for (auto &camera : cm.cameras()) {\n>> > +                     if (camera->streams().size() > 1) {\n>> > +                             cameraName = camera->id();\n>> > +                             cameraFound = true;\n>> > +                             cm.stop();\n>> > +                             break;\n>> > +                     }\n>> > +             }\n>> > +\n>> > +             if (!cameraFound) {\n>> > +                     cm.stop();\n>> > +                     return TestSkip;\n>> > +             }\n>> > +\n>> > +             g_autoptr(GstElement) convert0 =\n>> gst_element_factory_make(\"videoconvert\", \"convert0\");\n>> > +             g_autoptr(GstElement) convert1 =\n>> gst_element_factory_make(\"videoconvert\", \"convert1\");\n>>\n>> Why do you need a convert element ? AFAIK you are outputting into a\n>> fakesink it should not be an issue ?\n>>\n>\n> This is an artifact from the old code which used autovideosink but was\n> changed to fakesink. I'll test if removing it works, I'd want to use stats\n> property in future, I assume it won't work if I remove videoconvert.\n>\n> > +             g_autoptr(GstElement) sink0 =\n>> gst_element_factory_make(\"fakesink\", \"sink0\");\n>> > +             g_autoptr(GstElement) sink1 =\n>> gst_element_factory_make(\"fakesink\", \"sink1\");\n>> > +             g_autoptr(GstElement) queue0 =\n>> gst_element_factory_make(\"queue\", \"queue0\");\n>> > +             g_autoptr(GstElement) queue1 =\n>> gst_element_factory_make(\"queue\", \"queue1\");\n>> > +             g_object_ref_sink(convert0);\n>> > +             g_object_ref_sink(convert1);\n>> > +             g_object_ref_sink(sink0);\n>> > +             g_object_ref_sink(sink1);\n>> > +             g_object_ref_sink(queue0);\n>> > +             g_object_ref_sink(queue1);\n>>\n>> I don't really like that, why can't you use\n>> gst_parse_bin_from_description() for instance ?\n>> That way you would get a bin you could link to libcamerasrc.\n>>\n>\n> I think the answer to that lies in run() function, I'm doing using request\n> pads so, that won't be possible if I just use a bin. I maybe wrong, I'll\n> wait for Nicolas's comment as you said.\n>\n\ns/ I'm doing using request pads / I'm working with pads of the queue element\n\nNote: it is a long time since I really use GStreamer so I may not be\n>> up-to-date, Nicolas may a different comment, and he would be the one to\n>> follow ;-).\n>>\n>> > +\n>> > +             if (!convert0 || !convert1 || !sink0 || !sink1 || !queue0\n>> || !queue1) {\n>> > +                     g_printerr(\"Not all elements could be created.\n>> %p.%p.%p.%p.%p.%p\\n\",\n>> > +                                convert0, convert1, sink0, sink1,\n>> queue0, queue1);\n>> > +\n>> > +                     return TestFail;\n>> > +             }\n>> > +\n>> > +             if (createPipeline() != TestPass)\n>> > +                     return TestFail;\n>> > +\n>> > +             convert0_ = reinterpret_cast<GstElement\n>> *>(g_steal_pointer(&convert0));\n>> > +             convert1_ = reinterpret_cast<GstElement\n>> *>(g_steal_pointer(&convert1));\n>> > +             sink0_ = reinterpret_cast<GstElement\n>> *>(g_steal_pointer(&sink0));\n>> > +             sink1_ = reinterpret_cast<GstElement\n>> *>(g_steal_pointer(&sink1));\n>> > +             queue0_ = reinterpret_cast<GstElement\n>> *>(g_steal_pointer(&queue0));\n>> > +             queue1_ = reinterpret_cast<GstElement\n>> *>(g_steal_pointer(&queue1));\n>> > +\n>> > +             return TestPass;\n>> > +     }\n>> > +\n>> > +     int run() override\n>> > +     {\n>> > +             g_object_set(libcameraSrc_, \"camera-name\",\n>> cameraName.c_str(), NULL);\n>> > +\n>> > +             /* Build the pipeline */\n>> > +             gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,\n>> queue0_, queue1_,\n>> > +                              convert0_, convert1_, sink0_, sink1_,\n>> NULL);\n>> > +             if (gst_element_link_many(queue0_, convert0_, sink0_,\n>> NULL) != TRUE ||\n>> > +                 gst_element_link_many(queue1_, convert1_, sink1_,\n>> NULL) != TRUE) {\n>> > +                     g_printerr(\"Elements could not be linked.\\n\");\n>> > +                     return TestFail;\n>> > +             }\n>> > +\n>> > +             g_autoptr(GstPad) src_pad =\n>> gst_element_get_static_pad(libcameraSrc_, \"src\");\n>> > +             g_autoptr(GstPad) request_pad =\n>> gst_element_get_request_pad(libcameraSrc_, \"src_%u\");\n>> > +             GstPad *queue0_sink_pad =\n>> gst_element_get_static_pad(queue0_, \"sink\");\n>> > +             GstPad *queue1_sink_pad =\n>> gst_element_get_static_pad(queue1_, \"sink\");\n>> > +\n>> > +             if (gst_pad_link(src_pad, queue0_sink_pad) !=\n>> GST_PAD_LINK_OK\n>> > +                     || gst_pad_link(request_pad, queue1_sink_pad) !=\n>> GST_PAD_LINK_OK) {\n>> > +                     if (queue0_sink_pad)\n>> > +                             gst_object_unref(queue0_sink_pad);\n>> > +                     if (queue1_sink_pad)\n>> > +                             gst_object_unref(queue1_sink_pad);\n>> > +                     g_printerr(\"Pads could not be linked.\\n\");\n>> > +                     return TestFail;\n>> > +             }\n>> > +             gst_object_unref(queue0_sink_pad);\n>> > +             gst_object_unref(queue1_sink_pad);\n>> > +\n>> > +             if (startPipeline() != TestPass)\n>> > +                     return TestFail;\n>> > +\n>> > +             if (processEvent() != TestPass)\n>> > +                     return TestFail;\n>> > +\n>> > +             return TestPass;\n>> > +     }\n>> > +\n>> > +private:\n>> > +     std::string cameraName;\n>> > +     GstElement *convert0_;\n>> > +     GstElement *convert1_;\n>> > +     GstElement *sink0_;\n>> > +     GstElement *sink1_;\n>> > +     GstElement *queue0_;\n>> > +     GstElement *queue1_;\n>> > +};\n>> > +\n>> > +TEST_REGISTER(GstreamerMultiStreamTest)\n>> > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n>> > index aca53b920365..13652e87d05c 100644\n>> > --- a/test/gstreamer/meson.build\n>> > +++ b/test/gstreamer/meson.build\n>> > @@ -6,6 +6,7 @@ endif\n>> >\n>> >  gstreamer_tests = [\n>> >      ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n>> > +    ['multi_stream_test',   'gstreamer_multi_stream_test.cpp'],\n>> >  ]\n>> >  gstreamer_dep = dependency('gstreamer-1.0', required: true)\n>> >\n>> >\n>>\n>\n> Regards,\n> *Vedant Paranjape*\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 24C4CBDB1D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 14 Sep 2021 10:42:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8D4D46918A;\n\tTue, 14 Sep 2021 12:42:49 +0200 (CEST)","from mail-yb1-xb34.google.com (mail-yb1-xb34.google.com\n\t[IPv6:2607:f8b0:4864:20::b34])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id F10A460249\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 14 Sep 2021 12:42:47 +0200 (CEST)","by mail-yb1-xb34.google.com with SMTP id y13so27171192ybi.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 14 Sep 2021 03:42:47 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"kFgwVXZR\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=lqaTIWNx8Zp6XUUgM6CDAx0qV1AeKnPATc3lqoZ4/jk=;\n\tb=kFgwVXZRHiRF4h50Nn9GPh0i29ndKuE7JMXH9lk2CUt8Yi49PtX8xw3+ErvujpetlE\n\ttpntZ8elXOW4PhzUH1ZpRcFa3BNjVOVVASb0O4GPEOK2VDkNweGAZ0pla6ItKlVDyksz\n\tou8xwUkei51VOiS7F0bemTkYDzktmrexW8rCr/CIP39n4GRq4Ao19PlUBDY2mej7PB8n\n\tBDjjr8ewI08KX9fdUJZEdky/bMjjX4JrvsXZ4iakoKw4DWoHhCw3dHstOtT8lijl3Pov\n\tKFbCxQRHourDw1hngvJK53jBxkWV3Bd15IcPRdDakwTzyT5jQLCdgi8SDeg6R0cQUngu\n\tZKRg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=lqaTIWNx8Zp6XUUgM6CDAx0qV1AeKnPATc3lqoZ4/jk=;\n\tb=h5H3pYHA9ZWkQFW97FVurkpoAZDgrqOD+xI9LMfBlqsCFOpTnkf3vJMv22eAKE9IWH\n\tJgHhsNhv+fm4qbisYfcVPM+OjoewonnknobEulO6ZGiFzojMxajbRAN1z9F9Oxl4TeNd\n\tCNXJazhzlwdW6z30wrsSucJgDjr9UJRtktnnD+UcBXNu4UEZ3Se3k320FxMjOLUvoRi8\n\tCFMZaC3ApwT4/dxTgEjvX7jzs9Eu9pr5NIpEmyoK7PpX4lBMacbfqr6pHUwISaxwcIeA\n\tcsBMIQUE2AR4TyRncwBrhNHgRyWwPsRiWWBW5BWP8eU/xOMzueMCARAng2v+KpQa+bEy\n\ts1PQ==","X-Gm-Message-State":"AOAM530NAIuXAyGVDd89MkwbnJgjYyibmKPeAJo7e0S9nJGEz7CA/Ct1\n\ty7tZM6RykBwG1FWAvNIA1gPuVX4j9Jl8srVXTFqcWEKaA5D1uhCZ","X-Google-Smtp-Source":"ABdhPJx/v3J2+orD51fxgCXv+O3buXFkLlKQFep0UnHUy/NN1uM5zYKLpjWKReZviBn553+w6ISIGkkw8xiqpFw1w9w=","X-Received":"by 2002:a25:c504:: with SMTP id\n\tv4mr22183077ybe.308.1631616166782; \n\tTue, 14 Sep 2021 03:42:46 -0700 (PDT)","MIME-Version":"1.0","References":"<20210914084622.118939-1-vedantparanjape160201@gmail.com>\n\t<c8954628-2464-d131-86e4-3309ff853552@ideasonboard.com>\n\t<CACGrz-PTJuRe3ent+C=0uTKWeSSev6hgWRVdpp7O5YT=y0fMjg@mail.gmail.com>","In-Reply-To":"<CACGrz-PTJuRe3ent+C=0uTKWeSSev6hgWRVdpp7O5YT=y0fMjg@mail.gmail.com>","From":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Date":"Tue, 14 Sep 2021 16:12:35 +0530","Message-ID":"<CACGrz-P04wvPRBkUxOUhfD0_Hw=Ynj7jRFks93BumJDhEefxDA@mail.gmail.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"00000000000007e97405cbf23e95\"","Subject":"Re: [libcamera-devel] [PATCH v4] test: gstreamer: Add a test for\n\tgstreamer multi stream","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]