[{"id":18771,"web_url":"https://patchwork.libcamera.org/comment/18771/","msgid":"<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>","date":"2021-08-13T12:57:21","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Vedant,\n\nThank you for the patch.\n\nOn Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> This patch adds a test to test if single stream using\n> libcamera's gstreamer element works.\n> \n> Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n>  test/gstreamer/meson.build                    |  19 +++\n>  test/meson.build                              |   1 +\n>  3 files changed, 173 insertions(+)\n>  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n>  create mode 100644 test/gstreamer/meson.build\n> \n> diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp b/test/gstreamer/gstreamer_single_stream_test.cpp\n> new file mode 100644\n> index 00000000..eecd3274\n> --- /dev/null\n> +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> @@ -0,0 +1,153 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2021, Vedant Paranjape\n> + *\n> + * ipa_interface_test.cpp - Test the IPA interface\n> + */\n> +\n> +#include <iostream>\n> +\n> +#include <libcamera/base/utils.h>\n> +\n> +#include <gst/gst.h>\n> +\n> +#include \"test.h\"\n> +\n> +using namespace std;\n> +\n> +class GstreamerSingleStreamTest : public Test\n> +{\n> +protected:\n> +\tint init() override\n> +\t{\n> +\t\t/* Initialize GStreamer */\n> +\t\tGError *errInit = nullptr;\n> +\t\tif (!gst_init_check(nullptr, nullptr, &errInit)) {\n> +\t\t\tg_printerr(\"Could not initialize GStreamer: %s\\n\",\n> +\t\t\t\t   errInit ? errInit->message : \"unknown error\");\n> +\t\t\tif (errInit)\n> +\t\t\t\tg_error_free(errInit);\n> +\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/*\n> +\t\t* Remove the system libcamera plugin, if any, and add the\n> +\t\t* plugin from the build directory.\n> +\t\t*/\n\nMissing space before *\n\n> +\t\tGstRegistry *registry = gst_registry_get();\n> +\t\tGstPlugin *plugin = gst_registry_lookup(registry, \"libgstlibcamera.so\");\n> +\t\tif (plugin) {\n> +\t\t\tgst_registry_remove_plugin(registry, plugin);\n> +\t\t\tgst_object_unref(plugin);\n> +\t\t}\n> +\t\t\n\nExtra blank spaces at the end of the line.\n\n> +\t\tstd::string path = std::string(libcamera::utils::libcameraBuildPath()\n> +\t\t\t\t\t+ \"src/gstreamer\");\n\nNo need for calling the std::string constructor explictly,\nlibcamera::utils::libcameraBuildPath() returns an std::string and the\nresult of the operator+() call is also an std::string.\n\nYou should #include \"libcamera/internal/source_paths.h\"\" for\nlibcamera::utils::libcameraBuildPath().\n\nI'll fix these small issues when applying.\n\n> +\t\tif (!gst_registry_scan_path(registry, path.c_str())) {\n> +\t\t\tg_printerr(\"Failed to add plugin to registry\\n\");\n> +\t\t\tgst_deinit();\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/* Create the elements */\n> +\t\tlibcameraSrc_ = gst_element_factory_make(\"libcamerasrc\", \"libcamera\");\n> +\t\tconvert0_ = gst_element_factory_make(\"videoconvert\", \"convert0\");\n> +\t\tsink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> +\n> +\t\t/* Create the empty pipeline_ */\n> +\t\tpipeline_ = gst_pipeline_new(\"test-pipeline\");\n> +\n> +\t\tif (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_) {\n> +\t\t\tg_printerr(\"Not all elements could be created. %p.%p.%p.%p\\n\",\n> +\t\t\t\t   pipeline_, convert0_, sink0_, libcameraSrc_);\n> +\t\t\tif (pipeline_)\n> +\t\t\t\tgst_object_unref(pipeline_);\n> +\t\t\tif (convert0_)\n> +\t\t\t\tgst_object_unref(convert0_);\n> +\t\t\tif (sink0_)\n> +\t\t\t\tgst_object_unref(sink0_);\n> +\t\t\tif (libcameraSrc_)\n> +\t\t\t\tgst_object_unref(libcameraSrc_);\n> +\t\t\tgst_deinit();\n> +\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\treturn TestPass;\n> +\t}\n> +\n> +\tvoid cleanup() override\n> +\t{\n> +\t\tgst_object_unref(pipeline_);\n> +\t\tgst_deinit();\n> +\t}\n> +\n> +\tint run() override\n> +\t{\n> +\t\tGstStateChangeReturn ret;\n> +\t\tg_autoptr(GstBus) bus;\n> +\t\tg_autoptr(GstMessage) msg;\n> +\n> +\t\t/* Build the pipeline */\n> +\t\tgst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, convert0_, sink0_, NULL);\n> +\t\tif (gst_element_link_many(libcameraSrc_, convert0_, sink0_, NULL) != TRUE) {\n> +\t\t\tg_printerr(\"Elements could not be linked.\\n\");\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/* Start playing */\n> +\t\tret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> +\t\tif (ret == GST_STATE_CHANGE_FAILURE) {\n> +\t\t\tg_printerr(\"Unable to set the pipeline to the playing state.\\n\");\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/* Wait until error or EOS or timeout after 2 seconds */\n> +\t\tGstClockTime timeout = 2000000000;\n> +\t\tbus = gst_element_get_bus(pipeline_);\n> +\t\tmsg = gst_bus_timed_pop_filtered(bus, timeout,\n> +\t\t\t\t\t\t GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> +\t\tgst_element_set_state(pipeline_, GST_STATE_NULL);\n> +\n> +\t\t/* Parse error message */\n> +\t\tif (msg == NULL)\n> +\t\t\treturn TestPass;\n> +\n> +\t\tswitch (GST_MESSAGE_TYPE(msg)) {\n> +\t\tcase GST_MESSAGE_ERROR:\n> +\t\t\tgstreamer_print_error(msg);\n> +\t\t\tbreak;\n> +\t\tcase GST_MESSAGE_EOS:\n> +\t\t\tg_print(\"End-Of-Stream reached.\\n\");\n> +\t\t\tbreak;\n> +\t\tdefault:\n> +\t\t\tg_printerr(\"Unexpected message received.\\n\");\n> +\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +private:\n> +\tvoid gstreamer_print_error(GstMessage *msg)\n> +\t{\n> +\t\tGError *err;\n> +\t\tgchar *debug_info;\n> +\n> +\t\tgst_message_parse_error(msg, &err, &debug_info);\n> +\t\tg_printerr(\"Error received from element %s: %s\\n\",\n> +\t\t\t   GST_OBJECT_NAME(msg->src), err->message);\n> +\t\tg_printerr(\"Debugging information: %s\\n\",\n> +\t\t\t   debug_info ? debug_info : \"none\");\n> +\t\tg_clear_error(&err);\n> +\t\tg_free(debug_info);\n> +\t}\n> +\n> +\tGstElement *pipeline_;\n> +\tGstElement *libcameraSrc_;\n> +\tGstElement *convert0_;\n> +\tGstElement *sink0_;\n> +};\n> +\n> +TEST_REGISTER(GstreamerSingleStreamTest)\n> diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> new file mode 100644\n> index 00000000..b99aa0da\n> --- /dev/null\n> +++ b/test/gstreamer/meson.build\n> @@ -0,0 +1,19 @@\n> +# SPDX-License-Identifier: CC0-1.0\n> +\n> +if not gst_enabled\n> +    subdir_done()\n> +endif\n> +\n> +gstreamer_tests = [\n> +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> +]\n> +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> +\n> +foreach t : gstreamer_tests\n> +    exe = executable(t[0], t[1],\n> +                     dependencies : [libcamera_private, gstreamer_dep],\n> +                     link_with : test_libraries,\n> +                     include_directories : test_includes_internal)\n> +\n> +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> +endforeach\n> diff --git a/test/meson.build b/test/meson.build\n> index 3bceb5df..d0466f17 100644\n> --- a/test/meson.build\n> +++ b/test/meson.build\n> @@ -11,6 +11,7 @@ subdir('libtest')\n>  \n>  subdir('camera')\n>  subdir('controls')\n> +subdir('gstreamer')\n>  subdir('ipa')\n>  subdir('ipc')\n>  subdir('log')","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 D4EF1C3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 12:57:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C8E886888D;\n\tFri, 13 Aug 2021 14:57:27 +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 977AD687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 14:57:26 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 0B8814A1;\n\tFri, 13 Aug 2021 14:57:25 +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=\"FwCLV64o\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628859446;\n\tbh=/qizgt5O7MgoLWm6SFrCiXLXqkOmlA5Pn2QYNp+Btho=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=FwCLV64o0TuF/tZy7pnoQ0WM2mwQXLVrfVFghi0Gfpp9NVCT5mdywLF/HlRxnhR6i\n\twlwqMFPvH1M/lNTJLBTL40Sr9s/WezhepfKG+VVBnsTwKU+gneepsorfaTMU9AwqPZ\n\tPBZLvKF82jr3/BhstsElpYLJxq9969MZNpHwBx8c=","Date":"Fri, 13 Aug 2021 15:57:21 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Message-ID":"<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18772,"web_url":"https://patchwork.libcamera.org/comment/18772/","msgid":"<CACGrz-PkqQ8goqHe6ahi9KAYhs2ZPruAeUTd4UjTVQoNcZWEXQ@mail.gmail.com>","date":"2021-08-13T13:11:44","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":85,"url":"https://patchwork.libcamera.org/api/people/85/","name":"Vedant Paranjape","email":"vedantparanjape160201@gmail.com"},"content":"Thanks\n\nOn Fri, 13 Aug, 2021, 18:27 Laurent Pinchart, <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> Hi Vedant,\n>\n> Thank you for the patch.\n>\n> On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > This patch adds a test to test if single stream using\n> > libcamera's gstreamer element works.\n> >\n> > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > ---\n> >  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n> >  test/gstreamer/meson.build                    |  19 +++\n> >  test/meson.build                              |   1 +\n> >  3 files changed, 173 insertions(+)\n> >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> >  create mode 100644 test/gstreamer/meson.build\n> >\n> > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp\n> b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > new file mode 100644\n> > index 00000000..eecd3274\n> > --- /dev/null\n> > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > @@ -0,0 +1,153 @@\n> > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > +/*\n> > + * Copyright (C) 2021, Vedant Paranjape\n> > + *\n> > + * ipa_interface_test.cpp - Test the IPA interface\n> > + */\n> > +\n> > +#include <iostream>\n> > +\n> > +#include <libcamera/base/utils.h>\n> > +\n> > +#include <gst/gst.h>\n> > +\n> > +#include \"test.h\"\n> > +\n> > +using namespace std;\n> > +\n> > +class GstreamerSingleStreamTest : public Test\n> > +{\n> > +protected:\n> > +     int init() override\n> > +     {\n> > +             /* Initialize GStreamer */\n> > +             GError *errInit = nullptr;\n> > +             if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > +                     g_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > +                                errInit ? errInit->message : \"unknown\n> error\");\n> > +                     if (errInit)\n> > +                             g_error_free(errInit);\n> > +\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             /*\n> > +             * Remove the system libcamera plugin, if any, and add the\n> > +             * plugin from the build directory.\n> > +             */\n>\n> Missing space before *\n>\n> > +             GstRegistry *registry = gst_registry_get();\n> > +             GstPlugin *plugin = gst_registry_lookup(registry,\n> \"libgstlibcamera.so\");\n> > +             if (plugin) {\n> > +                     gst_registry_remove_plugin(registry, plugin);\n> > +                     gst_object_unref(plugin);\n> > +             }\n> > +\n>\n> Extra blank spaces at the end of the line.\n>\n> > +             std::string path =\n> std::string(libcamera::utils::libcameraBuildPath()\n> > +                                     + \"src/gstreamer\");\n>\n> No need for calling the std::string constructor explictly,\n> libcamera::utils::libcameraBuildPath() returns an std::string and the\n> result of the operator+() call is also an std::string.\n>\n> You should #include \"libcamera/internal/source_paths.h\"\" for\n> libcamera::utils::libcameraBuildPath().\n>\n\nI thought, It's \"internal\" so shouldn't be used in a public library. :D\n\nI'll fix these small issues when applying.\n>\n> > +             if (!gst_registry_scan_path(registry, path.c_str())) {\n> > +                     g_printerr(\"Failed to add plugin to registry\\n\");\n> > +                     gst_deinit();\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             /* Create the elements */\n> > +             libcameraSrc_ = gst_element_factory_make(\"libcamerasrc\",\n> \"libcamera\");\n> > +             convert0_ = gst_element_factory_make(\"videoconvert\",\n> \"convert0\");\n> > +             sink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > +\n> > +             /* Create the empty pipeline_ */\n> > +             pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > +\n> > +             if (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_)\n> {\n> > +                     g_printerr(\"Not all elements could be created.\n> %p.%p.%p.%p\\n\",\n> > +                                pipeline_, convert0_, sink0_,\n> libcameraSrc_);\n> > +                     if (pipeline_)\n> > +                             gst_object_unref(pipeline_);\n> > +                     if (convert0_)\n> > +                             gst_object_unref(convert0_);\n> > +                     if (sink0_)\n> > +                             gst_object_unref(sink0_);\n> > +                     if (libcameraSrc_)\n> > +                             gst_object_unref(libcameraSrc_);\n> > +                     gst_deinit();\n> > +\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             return TestPass;\n> > +     }\n> > +\n> > +     void cleanup() override\n> > +     {\n> > +             gst_object_unref(pipeline_);\n> > +             gst_deinit();\n> > +     }\n> > +\n> > +     int run() override\n> > +     {\n> > +             GstStateChangeReturn ret;\n> > +             g_autoptr(GstBus) bus;\n> > +             g_autoptr(GstMessage) msg;\n> > +\n> > +             /* Build the pipeline */\n> > +             gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,\n> convert0_, sink0_, NULL);\n> > +             if (gst_element_link_many(libcameraSrc_, convert0_,\n> sink0_, NULL) != TRUE) {\n> > +                     g_printerr(\"Elements could not be linked.\\n\");\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             /* Start playing */\n> > +             ret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > +             if (ret == GST_STATE_CHANGE_FAILURE) {\n> > +                     g_printerr(\"Unable to set the pipeline to the\n> playing state.\\n\");\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             /* Wait until error or EOS or timeout after 2 seconds */\n> > +             GstClockTime timeout = 2000000000;\n> > +             bus = gst_element_get_bus(pipeline_);\n> > +             msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > +\n> GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > +             gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > +\n> > +             /* Parse error message */\n> > +             if (msg == NULL)\n> > +                     return TestPass;\n> > +\n> > +             switch (GST_MESSAGE_TYPE(msg)) {\n> > +             case GST_MESSAGE_ERROR:\n> > +                     gstreamer_print_error(msg);\n> > +                     break;\n> > +             case GST_MESSAGE_EOS:\n> > +                     g_print(\"End-Of-Stream reached.\\n\");\n> > +                     break;\n> > +             default:\n> > +                     g_printerr(\"Unexpected message received.\\n\");\n> > +                     break;\n> > +             }\n> > +\n> > +             return TestFail;\n> > +     }\n> > +\n> > +private:\n> > +     void gstreamer_print_error(GstMessage *msg)\n> > +     {\n> > +             GError *err;\n> > +             gchar *debug_info;\n> > +\n> > +             gst_message_parse_error(msg, &err, &debug_info);\n> > +             g_printerr(\"Error received from element %s: %s\\n\",\n> > +                        GST_OBJECT_NAME(msg->src), err->message);\n> > +             g_printerr(\"Debugging information: %s\\n\",\n> > +                        debug_info ? debug_info : \"none\");\n> > +             g_clear_error(&err);\n> > +             g_free(debug_info);\n> > +     }\n> > +\n> > +     GstElement *pipeline_;\n> > +     GstElement *libcameraSrc_;\n> > +     GstElement *convert0_;\n> > +     GstElement *sink0_;\n> > +};\n> > +\n> > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > new file mode 100644\n> > index 00000000..b99aa0da\n> > --- /dev/null\n> > +++ b/test/gstreamer/meson.build\n> > @@ -0,0 +1,19 @@\n> > +# SPDX-License-Identifier: CC0-1.0\n> > +\n> > +if not gst_enabled\n> > +    subdir_done()\n> > +endif\n> > +\n> > +gstreamer_tests = [\n> > +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> > +]\n> > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > +\n> > +foreach t : gstreamer_tests\n> > +    exe = executable(t[0], t[1],\n> > +                     dependencies : [libcamera_private, gstreamer_dep],\n> > +                     link_with : test_libraries,\n> > +                     include_directories : test_includes_internal)\n> > +\n> > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > +endforeach\n> > diff --git a/test/meson.build b/test/meson.build\n> > index 3bceb5df..d0466f17 100644\n> > --- a/test/meson.build\n> > +++ b/test/meson.build\n> > @@ -11,6 +11,7 @@ subdir('libtest')\n> >\n> >  subdir('camera')\n> >  subdir('controls')\n> > +subdir('gstreamer')\n> >  subdir('ipa')\n> >  subdir('ipc')\n> >  subdir('log')\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\n\n\n\nRegards\n\nVedant 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 B8765BD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 13:11:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3893368891;\n\tFri, 13 Aug 2021 15:11:57 +0200 (CEST)","from mail-yb1-xb31.google.com (mail-yb1-xb31.google.com\n\t[IPv6:2607:f8b0:4864:20::b31])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 87EA1687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 15:11:56 +0200 (CEST)","by mail-yb1-xb31.google.com with SMTP id p4so18767689yba.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 06:11:56 -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=\"odTvO2kJ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=R0h9QIH13ruwW1PavnMrvtz1R2H9GxszNmp8di43fNA=;\n\tb=odTvO2kJYe8sPirZzvAwG7rWWHb7IkV8X/NhpQ6bIdbFm/2xR21v6V8HJV5k7Hi/Ii\n\tVL14L8HXkDv9Bf1CBB/AOYZ0b3ZAgeqJ+ii37Due64VXjed4c4PCWWfp+b/E1qEF5f7G\n\tiyTwfVLZMdJ1ote6FnFEI3aiHR189UvfmJXv9hk7FxrMH+i0frvdIRE9TIKc4M9qCnzS\n\tN3XZiOxEi0pern99qrltvD6WkF/ZS5QdMHMy2P3GsKXKowiBqpwqpwpfTBNZVsJ8+CZf\n\tNWG9JxiGuIjzI3TVRAhJFW74C++1x7U5yOTMwd2iD/ou5I4dBYMU5LuBvmdBPk76eWsJ\n\tAz4Q==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=R0h9QIH13ruwW1PavnMrvtz1R2H9GxszNmp8di43fNA=;\n\tb=ew+1gMXDUJZw2eWW7NhqL1HgZzHz+Kt8Qq7labq/LtOL4N6oIjUVYjecQD9VyZX4Im\n\twzUTDPFKKn8vkk7Lo/IqCvNPU0QneW+PhhGePHJ1+76KnAjQO3V9K5uhjntUP4Qg2I7F\n\tOkxJ+omVuK+H6b2JPAVEdfOhmpp8NmDcczXla0vrIP7uj1a1FU4hMNvl0n0fE89TKoe2\n\tamNtZlraJT1OFxGI9+5dcXDjSSH5YTKVxMmMkEwNa71vQdWORJbT83y8PEnfkq2uTUWO\n\tyXO0LxMDrEPBDEyldmfHiPtHIKBpqU7Lf1CPvBREUfb0xFdJgJYM1ql7BRYw7+gMzrVm\n\tFK4Q==","X-Gm-Message-State":"AOAM531YBMsCj3QkcglB1HYIqTh/tr/1pzWVgFtO3Z98RCsIi+epHoV/\n\tiW/lUdPGsb8EEQqjCGdYSteXjm/KrFWtaQaLn7g=","X-Google-Smtp-Source":"ABdhPJySeCKwfebgez+oKlmU9aaiTagA53mKJz5UH8hh6qEzMRKmjpkOLSFljtBhuB5XsnGtpycravVA9ZRwWo0UzZs=","X-Received":"by 2002:a5b:c52:: with SMTP id d18mr2860867ybr.248.1628860315324;\n\tFri, 13 Aug 2021 06:11:55 -0700 (PDT)","MIME-Version":"1.0","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>","In-Reply-To":"<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>","From":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Date":"Fri, 13 Aug 2021 18:41:44 +0530","Message-ID":"<CACGrz-PkqQ8goqHe6ahi9KAYhs2ZPruAeUTd4UjTVQoNcZWEXQ@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"0000000000007bd32c05c97098ae\"","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18773,"web_url":"https://patchwork.libcamera.org/comment/18773/","msgid":"<8e6ea949-d819-d233-bf59-1867ca3c8e16@ideasonboard.com>","date":"2021-08-13T13:13:10","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Vedant,\n\nOn 13/08/2021 11:43, Vedant Paranjape wrote:\n> This patch adds a test to test if single stream using\n> libcamera's gstreamer element works.\n> \n> Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n\nThis works on my machine now, thanks.\n\nTested-by: Kieran Bingham <kieran.bingham@@ideasonboard.com>\n\n> ---\n>  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n>  test/gstreamer/meson.build                    |  19 +++\n>  test/meson.build                              |   1 +\n>  3 files changed, 173 insertions(+)\n>  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n>  create mode 100644 test/gstreamer/meson.build\n> \n> diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp b/test/gstreamer/gstreamer_single_stream_test.cpp\n> new file mode 100644\n> index 00000000..eecd3274\n> --- /dev/null\n> +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> @@ -0,0 +1,153 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2021, Vedant Paranjape\n> + *\n> + * ipa_interface_test.cpp - Test the IPA interface\n> + */\n> +\n> +#include <iostream>\n> +\n> +#include <libcamera/base/utils.h>\n> +\n> +#include <gst/gst.h>\n> +\n> +#include \"test.h\"\n> +\n> +using namespace std;\n> +\n> +class GstreamerSingleStreamTest : public Test\n> +{\n> +protected:\n> +\tint init() override\n> +\t{\n> +\t\t/* Initialize GStreamer */\n> +\t\tGError *errInit = nullptr;\n> +\t\tif (!gst_init_check(nullptr, nullptr, &errInit)) {\n> +\t\t\tg_printerr(\"Could not initialize GStreamer: %s\\n\",\n> +\t\t\t\t   errInit ? errInit->message : \"unknown error\");\n> +\t\t\tif (errInit)\n> +\t\t\t\tg_error_free(errInit);\n> +\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/*\n> +\t\t* Remove the system libcamera plugin, if any, and add the\n> +\t\t* plugin from the build directory.\n> +\t\t*/\n> +\t\tGstRegistry *registry = gst_registry_get();\n> +\t\tGstPlugin *plugin = gst_registry_lookup(registry, \"libgstlibcamera.so\");\n> +\t\tif (plugin) {\n> +\t\t\tgst_registry_remove_plugin(registry, plugin);\n> +\t\t\tgst_object_unref(plugin);\n> +\t\t}\n> +\t\t\n> +\t\tstd::string path = std::string(libcamera::utils::libcameraBuildPath()\n> +\t\t\t\t\t+ \"src/gstreamer\");\n> +\t\tif (!gst_registry_scan_path(registry, path.c_str())) {\n> +\t\t\tg_printerr(\"Failed to add plugin to registry\\n\");\n> +\t\t\tgst_deinit();\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/* Create the elements */\n> +\t\tlibcameraSrc_ = gst_element_factory_make(\"libcamerasrc\", \"libcamera\");\n> +\t\tconvert0_ = gst_element_factory_make(\"videoconvert\", \"convert0\");\n> +\t\tsink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> +\n> +\t\t/* Create the empty pipeline_ */\n> +\t\tpipeline_ = gst_pipeline_new(\"test-pipeline\");\n> +\n> +\t\tif (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_) {\n> +\t\t\tg_printerr(\"Not all elements could be created. %p.%p.%p.%p\\n\",\n> +\t\t\t\t   pipeline_, convert0_, sink0_, libcameraSrc_);\n> +\t\t\tif (pipeline_)\n> +\t\t\t\tgst_object_unref(pipeline_);\n> +\t\t\tif (convert0_)\n> +\t\t\t\tgst_object_unref(convert0_);\n> +\t\t\tif (sink0_)\n> +\t\t\t\tgst_object_unref(sink0_);\n> +\t\t\tif (libcameraSrc_)\n> +\t\t\t\tgst_object_unref(libcameraSrc_);\n> +\t\t\tgst_deinit();\n> +\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\treturn TestPass;\n> +\t}\n> +\n> +\tvoid cleanup() override\n> +\t{\n> +\t\tgst_object_unref(pipeline_);\n> +\t\tgst_deinit();\n> +\t}\n> +\n> +\tint run() override\n> +\t{\n> +\t\tGstStateChangeReturn ret;\n> +\t\tg_autoptr(GstBus) bus;\n> +\t\tg_autoptr(GstMessage) msg;\n> +\n> +\t\t/* Build the pipeline */\n> +\t\tgst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, convert0_, sink0_, NULL);\n> +\t\tif (gst_element_link_many(libcameraSrc_, convert0_, sink0_, NULL) != TRUE) {\n> +\t\t\tg_printerr(\"Elements could not be linked.\\n\");\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/* Start playing */\n> +\t\tret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> +\t\tif (ret == GST_STATE_CHANGE_FAILURE) {\n> +\t\t\tg_printerr(\"Unable to set the pipeline to the playing state.\\n\");\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/* Wait until error or EOS or timeout after 2 seconds */\n> +\t\tGstClockTime timeout = 2000000000;\n> +\t\tbus = gst_element_get_bus(pipeline_);\n> +\t\tmsg = gst_bus_timed_pop_filtered(bus, timeout,\n> +\t\t\t\t\t\t GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> +\t\tgst_element_set_state(pipeline_, GST_STATE_NULL);\n> +\n> +\t\t/* Parse error message */\n> +\t\tif (msg == NULL)\n> +\t\t\treturn TestPass;\n> +\n> +\t\tswitch (GST_MESSAGE_TYPE(msg)) {\n> +\t\tcase GST_MESSAGE_ERROR:\n> +\t\t\tgstreamer_print_error(msg);\n> +\t\t\tbreak;\n> +\t\tcase GST_MESSAGE_EOS:\n> +\t\t\tg_print(\"End-Of-Stream reached.\\n\");\n> +\t\t\tbreak;\n> +\t\tdefault:\n> +\t\t\tg_printerr(\"Unexpected message received.\\n\");\n> +\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +private:\n> +\tvoid gstreamer_print_error(GstMessage *msg)\n> +\t{\n> +\t\tGError *err;\n> +\t\tgchar *debug_info;\n> +\n> +\t\tgst_message_parse_error(msg, &err, &debug_info);\n> +\t\tg_printerr(\"Error received from element %s: %s\\n\",\n> +\t\t\t   GST_OBJECT_NAME(msg->src), err->message);\n> +\t\tg_printerr(\"Debugging information: %s\\n\",\n> +\t\t\t   debug_info ? debug_info : \"none\");\n> +\t\tg_clear_error(&err);\n> +\t\tg_free(debug_info);\n> +\t}\n> +\n> +\tGstElement *pipeline_;\n> +\tGstElement *libcameraSrc_;\n> +\tGstElement *convert0_;\n> +\tGstElement *sink0_;\n> +};\n> +\n> +TEST_REGISTER(GstreamerSingleStreamTest)\n> diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> new file mode 100644\n> index 00000000..b99aa0da\n> --- /dev/null\n> +++ b/test/gstreamer/meson.build\n> @@ -0,0 +1,19 @@\n> +# SPDX-License-Identifier: CC0-1.0\n> +\n> +if not gst_enabled\n> +    subdir_done()\n> +endif\n> +\n> +gstreamer_tests = [\n> +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> +]\n> +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> +\n> +foreach t : gstreamer_tests\n> +    exe = executable(t[0], t[1],\n> +                     dependencies : [libcamera_private, gstreamer_dep],\n> +                     link_with : test_libraries,\n> +                     include_directories : test_includes_internal)\n> +\n> +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> +endforeach\n> diff --git a/test/meson.build b/test/meson.build\n> index 3bceb5df..d0466f17 100644\n> --- a/test/meson.build\n> +++ b/test/meson.build\n> @@ -11,6 +11,7 @@ subdir('libtest')\n>  \n>  subdir('camera')\n>  subdir('controls')\n> +subdir('gstreamer')\n>  subdir('ipa')\n>  subdir('ipc')\n>  subdir('log')\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 1EFD4BD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 13:13:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D8D046888D;\n\tFri, 13 Aug 2021 15:13:15 +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 3B11A687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 15:13:14 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AD5394A1;\n\tFri, 13 Aug 2021 15:13:13 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"gtcP6vlW\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628860393;\n\tbh=S2knaJIpasKsOZHQVgI+JjfCbZJsbYbdcXN2aT6jzGI=;\n\th=From:Subject:To:Cc:References:Date:In-Reply-To:From;\n\tb=gtcP6vlWrN1SH9YYZYoskwvlfNMO7oFv1CDnB+1WQHwmTOX9GFZYZas6y2DB0XR5y\n\tL2VvlPF0Hr0xW9kRKuVgMtkSdLP2u3pYMGjhxNq7MSjfmYMdPVgx8FR/5734noOz9H\n\tFDwAgvMRwSCSGsJIdOmQJEZfB1HjwNFnZhaqeTJs=","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>","Message-ID":"<8e6ea949-d819-d233-bf59-1867ca3c8e16@ideasonboard.com>","Date":"Fri, 13 Aug 2021 14:13:10 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.11.0","MIME-Version":"1.0","In-Reply-To":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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":18774,"web_url":"https://patchwork.libcamera.org/comment/18774/","msgid":"<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>","date":"2021-08-13T14:04:01","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> Hi Vedant,\n> \n> Thank you for the patch.\n> \n> On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > This patch adds a test to test if single stream using\n> > libcamera's gstreamer element works.\n> > \n> > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > ---\n> >  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n> >  test/gstreamer/meson.build                    |  19 +++\n> >  test/meson.build                              |   1 +\n> >  3 files changed, 173 insertions(+)\n> >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> >  create mode 100644 test/gstreamer/meson.build\n> > \n> > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > new file mode 100644\n> > index 00000000..eecd3274\n> > --- /dev/null\n> > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > @@ -0,0 +1,153 @@\n> > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > +/*\n> > + * Copyright (C) 2021, Vedant Paranjape\n> > + *\n> > + * ipa_interface_test.cpp - Test the IPA interface\n> > + */\n> > +\n> > +#include <iostream>\n> > +\n> > +#include <libcamera/base/utils.h>\n> > +\n> > +#include <gst/gst.h>\n> > +\n> > +#include \"test.h\"\n> > +\n> > +using namespace std;\n> > +\n> > +class GstreamerSingleStreamTest : public Test\n> > +{\n> > +protected:\n> > +\tint init() override\n> > +\t{\n> > +\t\t/* Initialize GStreamer */\n> > +\t\tGError *errInit = nullptr;\n> > +\t\tif (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > +\t\t\tg_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > +\t\t\t\t   errInit ? errInit->message : \"unknown error\");\n> > +\t\t\tif (errInit)\n> > +\t\t\t\tg_error_free(errInit);\n> > +\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> > +\t\t/*\n> > +\t\t* Remove the system libcamera plugin, if any, and add the\n> > +\t\t* plugin from the build directory.\n> > +\t\t*/\n> \n> Missing space before *\n> \n> > +\t\tGstRegistry *registry = gst_registry_get();\n> > +\t\tGstPlugin *plugin = gst_registry_lookup(registry, \"libgstlibcamera.so\");\n> > +\t\tif (plugin) {\n> > +\t\t\tgst_registry_remove_plugin(registry, plugin);\n> > +\t\t\tgst_object_unref(plugin);\n> > +\t\t}\n> > +\t\t\n> \n> Extra blank spaces at the end of the line.\n> \n> > +\t\tstd::string path = std::string(libcamera::utils::libcameraBuildPath()\n> > +\t\t\t\t\t+ \"src/gstreamer\");\n> \n> No need for calling the std::string constructor explictly,\n> libcamera::utils::libcameraBuildPath() returns an std::string and the\n> result of the operator+() call is also an std::string.\n> \n> You should #include \"libcamera/internal/source_paths.h\"\" for\n> libcamera::utils::libcameraBuildPath().\n> \n> I'll fix these small issues when applying.\n> \n> > +\t\tif (!gst_registry_scan_path(registry, path.c_str())) {\n> > +\t\t\tg_printerr(\"Failed to add plugin to registry\\n\");\n> > +\t\t\tgst_deinit();\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> > +\t\t/* Create the elements */\n> > +\t\tlibcameraSrc_ = gst_element_factory_make(\"libcamerasrc\", \"libcamera\");\n> > +\t\tconvert0_ = gst_element_factory_make(\"videoconvert\", \"convert0\");\n> > +\t\tsink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > +\n> > +\t\t/* Create the empty pipeline_ */\n> > +\t\tpipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > +\n> > +\t\tif (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_) {\n> > +\t\t\tg_printerr(\"Not all elements could be created. %p.%p.%p.%p\\n\",\n> > +\t\t\t\t   pipeline_, convert0_, sink0_, libcameraSrc_);\n> > +\t\t\tif (pipeline_)\n> > +\t\t\t\tgst_object_unref(pipeline_);\n> > +\t\t\tif (convert0_)\n> > +\t\t\t\tgst_object_unref(convert0_);\n> > +\t\t\tif (sink0_)\n> > +\t\t\t\tgst_object_unref(sink0_);\n> > +\t\t\tif (libcameraSrc_)\n> > +\t\t\t\tgst_object_unref(libcameraSrc_);\n> > +\t\t\tgst_deinit();\n> > +\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> > +\t\treturn TestPass;\n> > +\t}\n> > +\n> > +\tvoid cleanup() override\n> > +\t{\n> > +\t\tgst_object_unref(pipeline_);\n> > +\t\tgst_deinit();\n> > +\t}\n> > +\n> > +\tint run() override\n> > +\t{\n> > +\t\tGstStateChangeReturn ret;\n> > +\t\tg_autoptr(GstBus) bus;\n> > +\t\tg_autoptr(GstMessage) msg;\n\nI've also had to initialize those two variables to nullptr, to fix\n\nIn file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n                 from /usr/include/glib-2.0/glib/gtypes.h:32,\n                 from /usr/include/glib-2.0/glib/galloca.h:32,\n                 from /usr/include/glib-2.0/glib.h:30,\n                 from /usr/include/gstreamer-1.0/gst/gst.h:27,\n                 from ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n/usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int GstreamerSingleStreamTest::run()’:\n/usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used uninitialized in this function [-Werror=maybe-uninitialized]\n 1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }                                                              \\\n      |       ^~\n../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note: ‘msg’ was declared here\n  108 |   g_autoptr(GstMessage) msg;\n      |                         ^~~\n\nwhen cross-compiling for ARM.\n\n> > +\n> > +\t\t/* Build the pipeline */\n> > +\t\tgst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, convert0_, sink0_, NULL);\n> > +\t\tif (gst_element_link_many(libcameraSrc_, convert0_, sink0_, NULL) != TRUE) {\n> > +\t\t\tg_printerr(\"Elements could not be linked.\\n\");\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> > +\t\t/* Start playing */\n> > +\t\tret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > +\t\tif (ret == GST_STATE_CHANGE_FAILURE) {\n> > +\t\t\tg_printerr(\"Unable to set the pipeline to the playing state.\\n\");\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> > +\t\t/* Wait until error or EOS or timeout after 2 seconds */\n> > +\t\tGstClockTime timeout = 2000000000;\n> > +\t\tbus = gst_element_get_bus(pipeline_);\n> > +\t\tmsg = gst_bus_timed_pop_filtered(bus, timeout,\n> > +\t\t\t\t\t\t GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > +\t\tgst_element_set_state(pipeline_, GST_STATE_NULL);\n> > +\n> > +\t\t/* Parse error message */\n> > +\t\tif (msg == NULL)\n> > +\t\t\treturn TestPass;\n> > +\n> > +\t\tswitch (GST_MESSAGE_TYPE(msg)) {\n> > +\t\tcase GST_MESSAGE_ERROR:\n> > +\t\t\tgstreamer_print_error(msg);\n> > +\t\t\tbreak;\n> > +\t\tcase GST_MESSAGE_EOS:\n> > +\t\t\tg_print(\"End-Of-Stream reached.\\n\");\n> > +\t\t\tbreak;\n> > +\t\tdefault:\n> > +\t\t\tg_printerr(\"Unexpected message received.\\n\");\n> > +\t\t\tbreak;\n> > +\t\t}\n> > +\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +private:\n> > +\tvoid gstreamer_print_error(GstMessage *msg)\n> > +\t{\n> > +\t\tGError *err;\n> > +\t\tgchar *debug_info;\n> > +\n> > +\t\tgst_message_parse_error(msg, &err, &debug_info);\n> > +\t\tg_printerr(\"Error received from element %s: %s\\n\",\n> > +\t\t\t   GST_OBJECT_NAME(msg->src), err->message);\n> > +\t\tg_printerr(\"Debugging information: %s\\n\",\n> > +\t\t\t   debug_info ? debug_info : \"none\");\n> > +\t\tg_clear_error(&err);\n> > +\t\tg_free(debug_info);\n> > +\t}\n> > +\n> > +\tGstElement *pipeline_;\n> > +\tGstElement *libcameraSrc_;\n> > +\tGstElement *convert0_;\n> > +\tGstElement *sink0_;\n> > +};\n> > +\n> > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > new file mode 100644\n> > index 00000000..b99aa0da\n> > --- /dev/null\n> > +++ b/test/gstreamer/meson.build\n> > @@ -0,0 +1,19 @@\n> > +# SPDX-License-Identifier: CC0-1.0\n> > +\n> > +if not gst_enabled\n> > +    subdir_done()\n> > +endif\n> > +\n> > +gstreamer_tests = [\n> > +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> > +]\n> > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > +\n> > +foreach t : gstreamer_tests\n> > +    exe = executable(t[0], t[1],\n> > +                     dependencies : [libcamera_private, gstreamer_dep],\n> > +                     link_with : test_libraries,\n> > +                     include_directories : test_includes_internal)\n> > +\n> > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > +endforeach\n> > diff --git a/test/meson.build b/test/meson.build\n> > index 3bceb5df..d0466f17 100644\n> > --- a/test/meson.build\n> > +++ b/test/meson.build\n> > @@ -11,6 +11,7 @@ subdir('libtest')\n> >  \n> >  subdir('camera')\n> >  subdir('controls')\n> > +subdir('gstreamer')\n> >  subdir('ipa')\n> >  subdir('ipc')\n> >  subdir('log')","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 A5AFFBD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 14:04:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id ED6DF6888D;\n\tFri, 13 Aug 2021 16:04:08 +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 D0AFD687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 16:04:06 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4A6C34A1;\n\tFri, 13 Aug 2021 16:04:06 +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=\"qc84yzNa\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628863446;\n\tbh=vxSXq2G7Iz+1ZsM9IwkWtxIi8XDESjzBW+hdTWe9+2I=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=qc84yzNavsTzvEc9zslpEnD87TzMfZWMYHf4OJn/GuOOWjRH5KUBgYgYdcQdVPKnT\n\tZxR9mkMQjmfya1JDCel5M1JsMozUzwYGCu/us1INQkAyh6xFfb8REZYSMop3NkcgqN\n\tNRfA2n9MaMpze2ydyMHaMhhRazVhqfdfFxHF3NgQ=","Date":"Fri, 13 Aug 2021 17:04:01 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Message-ID":"<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18775,"web_url":"https://patchwork.libcamera.org/comment/18775/","msgid":"<CACGrz-Mah_5pauFehpDdiPLPMcgOD1r302UkrUqktoByQNsa8w@mail.gmail.com>","date":"2021-08-13T14:11:34","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":85,"url":"https://patchwork.libcamera.org/api/people/85/","name":"Vedant Paranjape","email":"vedantparanjape160201@gmail.com"},"content":"Hi Laurent,\nI'm just curious, what might be the reason that this error gets triggered\nonly on ARM and not on x86.\n\nRegards,\n*Vedant Paranjape*\n\nOn Fri, Aug 13, 2021 at 7:34 PM Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > Hi Vedant,\n> >\n> > Thank you for the patch.\n> >\n> > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > > This patch adds a test to test if single stream using\n> > > libcamera's gstreamer element works.\n> > >\n> > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > ---\n> > >  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n> > >  test/gstreamer/meson.build                    |  19 +++\n> > >  test/meson.build                              |   1 +\n> > >  3 files changed, 173 insertions(+)\n> > >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> > >  create mode 100644 test/gstreamer/meson.build\n> > >\n> > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp\n> b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > new file mode 100644\n> > > index 00000000..eecd3274\n> > > --- /dev/null\n> > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > @@ -0,0 +1,153 @@\n> > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > +/*\n> > > + * Copyright (C) 2021, Vedant Paranjape\n> > > + *\n> > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > + */\n> > > +\n> > > +#include <iostream>\n> > > +\n> > > +#include <libcamera/base/utils.h>\n> > > +\n> > > +#include <gst/gst.h>\n> > > +\n> > > +#include \"test.h\"\n> > > +\n> > > +using namespace std;\n> > > +\n> > > +class GstreamerSingleStreamTest : public Test\n> > > +{\n> > > +protected:\n> > > +   int init() override\n> > > +   {\n> > > +           /* Initialize GStreamer */\n> > > +           GError *errInit = nullptr;\n> > > +           if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > +                   g_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > > +                              errInit ? errInit->message : \"unknown\n> error\");\n> > > +                   if (errInit)\n> > > +                           g_error_free(errInit);\n> > > +\n> > > +                   return TestFail;\n> > > +           }\n> > > +\n> > > +           /*\n> > > +           * Remove the system libcamera plugin, if any, and add the\n> > > +           * plugin from the build directory.\n> > > +           */\n> >\n> > Missing space before *\n> >\n> > > +           GstRegistry *registry = gst_registry_get();\n> > > +           GstPlugin *plugin = gst_registry_lookup(registry,\n> \"libgstlibcamera.so\");\n> > > +           if (plugin) {\n> > > +                   gst_registry_remove_plugin(registry, plugin);\n> > > +                   gst_object_unref(plugin);\n> > > +           }\n> > > +\n> >\n> > Extra blank spaces at the end of the line.\n> >\n> > > +           std::string path =\n> std::string(libcamera::utils::libcameraBuildPath()\n> > > +                                   + \"src/gstreamer\");\n> >\n> > No need for calling the std::string constructor explictly,\n> > libcamera::utils::libcameraBuildPath() returns an std::string and the\n> > result of the operator+() call is also an std::string.\n> >\n> > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > libcamera::utils::libcameraBuildPath().\n> >\n> > I'll fix these small issues when applying.\n> >\n> > > +           if (!gst_registry_scan_path(registry, path.c_str())) {\n> > > +                   g_printerr(\"Failed to add plugin to registry\\n\");\n> > > +                   gst_deinit();\n> > > +                   return TestFail;\n> > > +           }\n> > > +\n> > > +           /* Create the elements */\n> > > +           libcameraSrc_ = gst_element_factory_make(\"libcamerasrc\",\n> \"libcamera\");\n> > > +           convert0_ = gst_element_factory_make(\"videoconvert\",\n> \"convert0\");\n> > > +           sink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > > +\n> > > +           /* Create the empty pipeline_ */\n> > > +           pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > +\n> > > +           if (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_)\n> {\n> > > +                   g_printerr(\"Not all elements could be created.\n> %p.%p.%p.%p\\n\",\n> > > +                              pipeline_, convert0_, sink0_,\n> libcameraSrc_);\n> > > +                   if (pipeline_)\n> > > +                           gst_object_unref(pipeline_);\n> > > +                   if (convert0_)\n> > > +                           gst_object_unref(convert0_);\n> > > +                   if (sink0_)\n> > > +                           gst_object_unref(sink0_);\n> > > +                   if (libcameraSrc_)\n> > > +                           gst_object_unref(libcameraSrc_);\n> > > +                   gst_deinit();\n> > > +\n> > > +                   return TestFail;\n> > > +           }\n> > > +\n> > > +           return TestPass;\n> > > +   }\n> > > +\n> > > +   void cleanup() override\n> > > +   {\n> > > +           gst_object_unref(pipeline_);\n> > > +           gst_deinit();\n> > > +   }\n> > > +\n> > > +   int run() override\n> > > +   {\n> > > +           GstStateChangeReturn ret;\n> > > +           g_autoptr(GstBus) bus;\n> > > +           g_autoptr(GstMessage) msg;\n>\n> I've also had to initialize those two variables to nullptr, to fix\n>\n> In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n>                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n>                  from /usr/include/glib-2.0/glib/galloca.h:32,\n>                  from /usr/include/glib-2.0/glib.h:30,\n>                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n>                  from\n> ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> /usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int\n> GstreamerSingleStreamTest::run()’:\n> /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used\n> uninitialized in this function [-Werror=maybe-uninitialized]\n>  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }\n>                                               \\\n>       |       ^~\n> ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note: ‘msg’\n> was declared here\n>   108 |   g_autoptr(GstMessage) msg;\n>       |                         ^~~\n>\n> when cross-compiling for ARM.\n>\n> > > +\n> > > +           /* Build the pipeline */\n> > > +           gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,\n> convert0_, sink0_, NULL);\n> > > +           if (gst_element_link_many(libcameraSrc_, convert0_,\n> sink0_, NULL) != TRUE) {\n> > > +                   g_printerr(\"Elements could not be linked.\\n\");\n> > > +                   return TestFail;\n> > > +           }\n> > > +\n> > > +           /* Start playing */\n> > > +           ret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > > +           if (ret == GST_STATE_CHANGE_FAILURE) {\n> > > +                   g_printerr(\"Unable to set the pipeline to the\n> playing state.\\n\");\n> > > +                   return TestFail;\n> > > +           }\n> > > +\n> > > +           /* Wait until error or EOS or timeout after 2 seconds */\n> > > +           GstClockTime timeout = 2000000000;\n> > > +           bus = gst_element_get_bus(pipeline_);\n> > > +           msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > +\n> GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > +           gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > +\n> > > +           /* Parse error message */\n> > > +           if (msg == NULL)\n> > > +                   return TestPass;\n> > > +\n> > > +           switch (GST_MESSAGE_TYPE(msg)) {\n> > > +           case GST_MESSAGE_ERROR:\n> > > +                   gstreamer_print_error(msg);\n> > > +                   break;\n> > > +           case GST_MESSAGE_EOS:\n> > > +                   g_print(\"End-Of-Stream reached.\\n\");\n> > > +                   break;\n> > > +           default:\n> > > +                   g_printerr(\"Unexpected message received.\\n\");\n> > > +                   break;\n> > > +           }\n> > > +\n> > > +           return TestFail;\n> > > +   }\n> > > +\n> > > +private:\n> > > +   void gstreamer_print_error(GstMessage *msg)\n> > > +   {\n> > > +           GError *err;\n> > > +           gchar *debug_info;\n> > > +\n> > > +           gst_message_parse_error(msg, &err, &debug_info);\n> > > +           g_printerr(\"Error received from element %s: %s\\n\",\n> > > +                      GST_OBJECT_NAME(msg->src), err->message);\n> > > +           g_printerr(\"Debugging information: %s\\n\",\n> > > +                      debug_info ? debug_info : \"none\");\n> > > +           g_clear_error(&err);\n> > > +           g_free(debug_info);\n> > > +   }\n> > > +\n> > > +   GstElement *pipeline_;\n> > > +   GstElement *libcameraSrc_;\n> > > +   GstElement *convert0_;\n> > > +   GstElement *sink0_;\n> > > +};\n> > > +\n> > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > > new file mode 100644\n> > > index 00000000..b99aa0da\n> > > --- /dev/null\n> > > +++ b/test/gstreamer/meson.build\n> > > @@ -0,0 +1,19 @@\n> > > +# SPDX-License-Identifier: CC0-1.0\n> > > +\n> > > +if not gst_enabled\n> > > +    subdir_done()\n> > > +endif\n> > > +\n> > > +gstreamer_tests = [\n> > > +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> > > +]\n> > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > +\n> > > +foreach t : gstreamer_tests\n> > > +    exe = executable(t[0], t[1],\n> > > +                     dependencies : [libcamera_private,\n> gstreamer_dep],\n> > > +                     link_with : test_libraries,\n> > > +                     include_directories : test_includes_internal)\n> > > +\n> > > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > > +endforeach\n> > > diff --git a/test/meson.build b/test/meson.build\n> > > index 3bceb5df..d0466f17 100644\n> > > --- a/test/meson.build\n> > > +++ b/test/meson.build\n> > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > >\n> > >  subdir('camera')\n> > >  subdir('controls')\n> > > +subdir('gstreamer')\n> > >  subdir('ipa')\n> > >  subdir('ipc')\n> > >  subdir('log')\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\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 7513AC3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 14:11:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DE0806888E;\n\tFri, 13 Aug 2021 16:11:49 +0200 (CEST)","from mail-yb1-xb2b.google.com (mail-yb1-xb2b.google.com\n\t[IPv6:2607:f8b0:4864:20::b2b])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A4019687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 16:11:48 +0200 (CEST)","by mail-yb1-xb2b.google.com with SMTP id k11so19070775ybf.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 07:11:48 -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=\"hWkMsuWL\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=1qj1kTuKa8g7ZqFy92eBuUGmaRxmn3/KcPTxe8iah1I=;\n\tb=hWkMsuWLZ3OuL3AmLat7Oc4TOj9JQiRnt3demRveFyhsuiAzlnyHIgZVZu9pNHqXgh\n\tNGhKdS1v0p+b6/TekwKSk9T1SEV/lH0AKG4D8eJFgQTRfqGrkOO/188MDeMPnFkRn41y\n\tZn10vymB77rZCoi3DijPqjgGDoZj1Yx9ohdx2z/PRId6stbdpALoU1Z/uobsDStzeX3y\n\tYdj1DIOjdG2CBQ9iE3ncj1YxXbQ5e9xnJsoU9VEtBvKkxW8cgL32WDiL8l14OA+iTPdO\n\toLA9RBVMNqRvC6C/aR82mmW9PjclrF91e/ryiNrG8V+HYPgdhRp64E8r5PUrhSE8fZOc\n\tkyWA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=1qj1kTuKa8g7ZqFy92eBuUGmaRxmn3/KcPTxe8iah1I=;\n\tb=khuwAeG5+W7pTi5yDsLYD5mguJliAjmncilocrZyHdne80XBdZRN7KD9u4+W+FKIcM\n\tWHD8FJkN0oginsJRm2zYNyTziZP45ivKgWlOGq8hUsaafeWukWqbB1LxPKtElTqAjUM3\n\tJUlMaizyDAU0KUlK6o16743JlNSBkKQDwieHoXqbbIpSOVWwwYOc3HaXo8r2S2RS+mJ6\n\tmgztBJ2snm5F43TK7R3pWmDjv8u6mTthM8C1nVOahsQlGnMl3isXP0Y0HKXlRjMm1kSo\n\tYTetGvbwBld25Vz94vbcZfi57XksJsE/obJRMzddVWkTXLGvDo6YG1BfFtoeA7y4VJHH\n\ttAYw==","X-Gm-Message-State":"AOAM531d9sUnhLZ/Xun3GN2KH/yVXQ5H9eKIFgvAZ0RZlvtyvISzcUf4\n\tCcCoCJoc9yGAgWXeNH4rDubXztx0Cw+C6W+gEeUEVSL75jQ=","X-Google-Smtp-Source":"ABdhPJwDEhQR55LiQwCPON39fJu1XE00r2jgsIizwCOb0imwmT5TFXwrkF9xLvl9ZKaIv8pJN4sb04vIbYXJ+hphp0E=","X-Received":"by 2002:a25:3f85:: with SMTP id\n\tm127mr3256829yba.21.1628863907400; \n\tFri, 13 Aug 2021 07:11:47 -0700 (PDT)","MIME-Version":"1.0","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>","In-Reply-To":"<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>","From":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Date":"Fri, 13 Aug 2021 19:41:34 +0530","Message-ID":"<CACGrz-Mah_5pauFehpDdiPLPMcgOD1r302UkrUqktoByQNsa8w@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"000000000000968f5305c9716eb4\"","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18777,"web_url":"https://patchwork.libcamera.org/comment/18777/","msgid":"<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>","date":"2021-08-13T14:37:16","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Aug 13, 2021 at 05:04:01PM +0300, Laurent Pinchart wrote:\n> On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > Hi Vedant,\n> > \n> > Thank you for the patch.\n> > \n> > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > > This patch adds a test to test if single stream using\n> > > libcamera's gstreamer element works.\n> > > \n> > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > ---\n> > >  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n> > >  test/gstreamer/meson.build                    |  19 +++\n> > >  test/meson.build                              |   1 +\n> > >  3 files changed, 173 insertions(+)\n> > >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> > >  create mode 100644 test/gstreamer/meson.build\n> > > \n> > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > new file mode 100644\n> > > index 00000000..eecd3274\n> > > --- /dev/null\n> > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > @@ -0,0 +1,153 @@\n> > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > +/*\n> > > + * Copyright (C) 2021, Vedant Paranjape\n> > > + *\n> > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > + */\n> > > +\n> > > +#include <iostream>\n> > > +\n> > > +#include <libcamera/base/utils.h>\n> > > +\n> > > +#include <gst/gst.h>\n> > > +\n> > > +#include \"test.h\"\n> > > +\n> > > +using namespace std;\n> > > +\n> > > +class GstreamerSingleStreamTest : public Test\n> > > +{\n> > > +protected:\n> > > +\tint init() override\n> > > +\t{\n> > > +\t\t/* Initialize GStreamer */\n> > > +\t\tGError *errInit = nullptr;\n> > > +\t\tif (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > +\t\t\tg_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > > +\t\t\t\t   errInit ? errInit->message : \"unknown error\");\n> > > +\t\t\tif (errInit)\n> > > +\t\t\t\tg_error_free(errInit);\n> > > +\n> > > +\t\t\treturn TestFail;\n> > > +\t\t}\n> > > +\n> > > +\t\t/*\n> > > +\t\t* Remove the system libcamera plugin, if any, and add the\n> > > +\t\t* plugin from the build directory.\n> > > +\t\t*/\n> > \n> > Missing space before *\n> > \n> > > +\t\tGstRegistry *registry = gst_registry_get();\n> > > +\t\tGstPlugin *plugin = gst_registry_lookup(registry, \"libgstlibcamera.so\");\n> > > +\t\tif (plugin) {\n> > > +\t\t\tgst_registry_remove_plugin(registry, plugin);\n> > > +\t\t\tgst_object_unref(plugin);\n> > > +\t\t}\n> > > +\t\t\n> > \n> > Extra blank spaces at the end of the line.\n> > \n> > > +\t\tstd::string path = std::string(libcamera::utils::libcameraBuildPath()\n> > > +\t\t\t\t\t+ \"src/gstreamer\");\n> > \n> > No need for calling the std::string constructor explictly,\n> > libcamera::utils::libcameraBuildPath() returns an std::string and the\n> > result of the operator+() call is also an std::string.\n> > \n> > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > libcamera::utils::libcameraBuildPath().\n> > \n> > I'll fix these small issues when applying.\n> > \n> > > +\t\tif (!gst_registry_scan_path(registry, path.c_str())) {\n> > > +\t\t\tg_printerr(\"Failed to add plugin to registry\\n\");\n> > > +\t\t\tgst_deinit();\n> > > +\t\t\treturn TestFail;\n> > > +\t\t}\n> > > +\n> > > +\t\t/* Create the elements */\n> > > +\t\tlibcameraSrc_ = gst_element_factory_make(\"libcamerasrc\", \"libcamera\");\n\nAnd now I'm getting a failure here :-( When compiling with gcc, and with\nthe meson b_sanitize option set to 'address', this call returns null.\n\n10/64 libcamera:gstreamer / single_stream_test                           FAIL            0.48s   exit status 1\n>>> MALLOC_PERTURB_=101 build/x86-gcc-11.1.0/test/gstreamer/single_stream_test\n――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― ✀  ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\nstderr:\n==14992==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n==14993==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\nNot all elements could be created. 0x6290000241f0.0x61a000019950.0x61a00001a670.(nil)\n\n=================================================================\n==14990==ERROR: LeakSanitizer: detected memory leaks\n\nDirect leak of 16384 byte(s) in 1 object(s) allocated from:\n    #0 0x7f9daade1ac7 in __interceptor_malloc /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n    #1 0x7f9da776a938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n\nSUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n\n11/64 libcamera:ipa / ipa_module_test                                    OK              0.08s\n\nInterestingly, if I run the test with\n\nLD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libasan.so.6 ./test/gstreamer/single_stream_test\n\nthen is runs fine:\n\n[25:59:46.412146534] [18711]  INFO IPAManager ipa_manager.cpp:138 libcamera is not installed. Adding '[...]/build/x86-gcc-11.1.0/src/ipa' to the IPA search path\n[25:59:46.413634330] [18711]  INFO Camera camera_manager.cpp:294 libcamera v0.0.0+2881-24c1e91b-dirty (2021-08-13T17:24:37+03:00)\n[25:59:46.663097368] [18714]  WARN CameraSensorProperties camera_sensor_properties.cpp:123 No static properties available for 'Sensor B'\n[25:59:46.663129122] [18714]  WARN CameraSensorProperties camera_sensor_properties.cpp:125 Please consider updating the camera sensor properties database\n[25:59:46.663156409] [18714]  WARN CameraSensor camera_sensor.cpp:403 'Sensor B': Failed to retrieve the camera location\n[25:59:46.664891182] [18714]  INFO IPAProxy ipa_proxy.cpp:130 libcamera is not installed. Loading IPA configuration from '[...]/src/ipa/vimc/data'\n[25:59:46.680563655] [18715]  INFO Camera camera.cpp:870 configuring streams: (0) 160x120-YUYV\n\n=================================================================\n==18711==ERROR: LeakSanitizer: detected memory leaks\n\nDirect leak of 16384 byte(s) in 1 object(s) allocated from:\n    #0 0x7effa6393ac7 in __interceptor_malloc /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n    #1 0x7effa57be938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n\nSUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n\nThe leak is a known glib issue, caught by valgrind too, so I'm not\nworried about it. The test failing to run is however a blocker.\n\nVedant, can you reproduce the failure with the address sanitizer ?\n\n> > > +\t\tconvert0_ = gst_element_factory_make(\"videoconvert\", \"convert0\");\n> > > +\t\tsink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > > +\n> > > +\t\t/* Create the empty pipeline_ */\n> > > +\t\tpipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > +\n> > > +\t\tif (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_) {\n> > > +\t\t\tg_printerr(\"Not all elements could be created. %p.%p.%p.%p\\n\",\n> > > +\t\t\t\t   pipeline_, convert0_, sink0_, libcameraSrc_);\n> > > +\t\t\tif (pipeline_)\n> > > +\t\t\t\tgst_object_unref(pipeline_);\n> > > +\t\t\tif (convert0_)\n> > > +\t\t\t\tgst_object_unref(convert0_);\n> > > +\t\t\tif (sink0_)\n> > > +\t\t\t\tgst_object_unref(sink0_);\n> > > +\t\t\tif (libcameraSrc_)\n> > > +\t\t\t\tgst_object_unref(libcameraSrc_);\n> > > +\t\t\tgst_deinit();\n> > > +\n> > > +\t\t\treturn TestFail;\n> > > +\t\t}\n> > > +\n> > > +\t\treturn TestPass;\n> > > +\t}\n> > > +\n> > > +\tvoid cleanup() override\n> > > +\t{\n> > > +\t\tgst_object_unref(pipeline_);\n> > > +\t\tgst_deinit();\n> > > +\t}\n> > > +\n> > > +\tint run() override\n> > > +\t{\n> > > +\t\tGstStateChangeReturn ret;\n> > > +\t\tg_autoptr(GstBus) bus;\n> > > +\t\tg_autoptr(GstMessage) msg;\n> \n> I've also had to initialize those two variables to nullptr, to fix\n> \n> In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n>                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n>                  from /usr/include/glib-2.0/glib/galloca.h:32,\n>                  from /usr/include/glib-2.0/glib.h:30,\n>                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n>                  from ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> /usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int GstreamerSingleStreamTest::run()’:\n> /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used uninitialized in this function [-Werror=maybe-uninitialized]\n>  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }                                                              \\\n>       |       ^~\n> ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note: ‘msg’ was declared here\n>   108 |   g_autoptr(GstMessage) msg;\n>       |                         ^~~\n> \n> when cross-compiling for ARM.\n> \n> > > +\n> > > +\t\t/* Build the pipeline */\n> > > +\t\tgst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, convert0_, sink0_, NULL);\n> > > +\t\tif (gst_element_link_many(libcameraSrc_, convert0_, sink0_, NULL) != TRUE) {\n> > > +\t\t\tg_printerr(\"Elements could not be linked.\\n\");\n> > > +\t\t\treturn TestFail;\n> > > +\t\t}\n> > > +\n> > > +\t\t/* Start playing */\n> > > +\t\tret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > > +\t\tif (ret == GST_STATE_CHANGE_FAILURE) {\n> > > +\t\t\tg_printerr(\"Unable to set the pipeline to the playing state.\\n\");\n> > > +\t\t\treturn TestFail;\n> > > +\t\t}\n> > > +\n> > > +\t\t/* Wait until error or EOS or timeout after 2 seconds */\n> > > +\t\tGstClockTime timeout = 2000000000;\n> > > +\t\tbus = gst_element_get_bus(pipeline_);\n> > > +\t\tmsg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > +\t\t\t\t\t\t GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > +\t\tgst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > +\n> > > +\t\t/* Parse error message */\n> > > +\t\tif (msg == NULL)\n> > > +\t\t\treturn TestPass;\n> > > +\n> > > +\t\tswitch (GST_MESSAGE_TYPE(msg)) {\n> > > +\t\tcase GST_MESSAGE_ERROR:\n> > > +\t\t\tgstreamer_print_error(msg);\n> > > +\t\t\tbreak;\n> > > +\t\tcase GST_MESSAGE_EOS:\n> > > +\t\t\tg_print(\"End-Of-Stream reached.\\n\");\n> > > +\t\t\tbreak;\n> > > +\t\tdefault:\n> > > +\t\t\tg_printerr(\"Unexpected message received.\\n\");\n> > > +\t\t\tbreak;\n> > > +\t\t}\n> > > +\n> > > +\t\treturn TestFail;\n> > > +\t}\n> > > +\n> > > +private:\n> > > +\tvoid gstreamer_print_error(GstMessage *msg)\n> > > +\t{\n> > > +\t\tGError *err;\n> > > +\t\tgchar *debug_info;\n> > > +\n> > > +\t\tgst_message_parse_error(msg, &err, &debug_info);\n> > > +\t\tg_printerr(\"Error received from element %s: %s\\n\",\n> > > +\t\t\t   GST_OBJECT_NAME(msg->src), err->message);\n> > > +\t\tg_printerr(\"Debugging information: %s\\n\",\n> > > +\t\t\t   debug_info ? debug_info : \"none\");\n> > > +\t\tg_clear_error(&err);\n> > > +\t\tg_free(debug_info);\n> > > +\t}\n> > > +\n> > > +\tGstElement *pipeline_;\n> > > +\tGstElement *libcameraSrc_;\n> > > +\tGstElement *convert0_;\n> > > +\tGstElement *sink0_;\n> > > +};\n> > > +\n> > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > > new file mode 100644\n> > > index 00000000..b99aa0da\n> > > --- /dev/null\n> > > +++ b/test/gstreamer/meson.build\n> > > @@ -0,0 +1,19 @@\n> > > +# SPDX-License-Identifier: CC0-1.0\n> > > +\n> > > +if not gst_enabled\n> > > +    subdir_done()\n> > > +endif\n> > > +\n> > > +gstreamer_tests = [\n> > > +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> > > +]\n> > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > +\n> > > +foreach t : gstreamer_tests\n> > > +    exe = executable(t[0], t[1],\n> > > +                     dependencies : [libcamera_private, gstreamer_dep],\n> > > +                     link_with : test_libraries,\n> > > +                     include_directories : test_includes_internal)\n> > > +\n> > > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > > +endforeach\n> > > diff --git a/test/meson.build b/test/meson.build\n> > > index 3bceb5df..d0466f17 100644\n> > > --- a/test/meson.build\n> > > +++ b/test/meson.build\n> > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > >  \n> > >  subdir('camera')\n> > >  subdir('controls')\n> > > +subdir('gstreamer')\n> > >  subdir('ipa')\n> > >  subdir('ipc')\n> > >  subdir('log')","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 52084BD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 14:37:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1CC3F6888F;\n\tFri, 13 Aug 2021 16:37:23 +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 46BBB687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 16:37:21 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id CCB638F;\n\tFri, 13 Aug 2021 16:37:20 +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=\"Smt6nOOB\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628865441;\n\tbh=Z3DjWrWrW7BPJ35upPJ8JjBYhW7fk9Wp+ebCsv9SpqU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Smt6nOOBRjNvdagpKG8mSgrl7a1BM07ue7G2lpls9/zuNR3JU/SoXubRDPI5xvek7\n\tBj+y0+8gtKPnXwgKWbHDstNqE4cney+5M4Wf0TJSD/RJ6kTdr8iwgCC+KtisNPDdpf\n\tK77ErRe1+cFc6L5qVLwgpGFOlJHjNX+V6OU0xhfY=","Date":"Fri, 13 Aug 2021 17:37:16 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Message-ID":"<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18778,"web_url":"https://patchwork.libcamera.org/comment/18778/","msgid":"<YRaE6ZWNywis/St7@pendragon.ideasonboard.com>","date":"2021-08-13T14:42:49","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Aug 13, 2021 at 07:41:34PM +0530, Vedant Paranjape wrote:\n> Hi Laurent,\n> I'm just curious, what might be the reason that this error gets triggered\n> only on ARM and not on x86.\n\nI don't know, I haven't investigated. It may be that my ARM cross-build\nenvironment uses a different glib version, not sure.\n\nI'm actually a bit surprised that no other compiler warned about this,\nit seems to be a legitimate issue.\n\n> On Fri, Aug 13, 2021 at 7:34 PM Laurent Pinchart wrote:\n> > On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > > > This patch adds a test to test if single stream using\n> > > > libcamera's gstreamer element works.\n> > > >\n> > > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> > > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > > ---\n> > > >  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n> > > >  test/gstreamer/meson.build                    |  19 +++\n> > > >  test/meson.build                              |   1 +\n> > > >  3 files changed, 173 insertions(+)\n> > > >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> > > >  create mode 100644 test/gstreamer/meson.build\n> > > >\n> > > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp\n> > b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > new file mode 100644\n> > > > index 00000000..eecd3274\n> > > > --- /dev/null\n> > > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > @@ -0,0 +1,153 @@\n> > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > > +/*\n> > > > + * Copyright (C) 2021, Vedant Paranjape\n> > > > + *\n> > > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > > + */\n> > > > +\n> > > > +#include <iostream>\n> > > > +\n> > > > +#include <libcamera/base/utils.h>\n> > > > +\n> > > > +#include <gst/gst.h>\n> > > > +\n> > > > +#include \"test.h\"\n> > > > +\n> > > > +using namespace std;\n> > > > +\n> > > > +class GstreamerSingleStreamTest : public Test\n> > > > +{\n> > > > +protected:\n> > > > +   int init() override\n> > > > +   {\n> > > > +           /* Initialize GStreamer */\n> > > > +           GError *errInit = nullptr;\n> > > > +           if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > > +                   g_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > > > +                              errInit ? errInit->message : \"unknown\n> > error\");\n> > > > +                   if (errInit)\n> > > > +                           g_error_free(errInit);\n> > > > +\n> > > > +                   return TestFail;\n> > > > +           }\n> > > > +\n> > > > +           /*\n> > > > +           * Remove the system libcamera plugin, if any, and add the\n> > > > +           * plugin from the build directory.\n> > > > +           */\n> > >\n> > > Missing space before *\n> > >\n> > > > +           GstRegistry *registry = gst_registry_get();\n> > > > +           GstPlugin *plugin = gst_registry_lookup(registry,\n> > \"libgstlibcamera.so\");\n> > > > +           if (plugin) {\n> > > > +                   gst_registry_remove_plugin(registry, plugin);\n> > > > +                   gst_object_unref(plugin);\n> > > > +           }\n> > > > +\n> > >\n> > > Extra blank spaces at the end of the line.\n> > >\n> > > > +           std::string path =\n> > std::string(libcamera::utils::libcameraBuildPath()\n> > > > +                                   + \"src/gstreamer\");\n> > >\n> > > No need for calling the std::string constructor explictly,\n> > > libcamera::utils::libcameraBuildPath() returns an std::string and the\n> > > result of the operator+() call is also an std::string.\n> > >\n> > > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > > libcamera::utils::libcameraBuildPath().\n> > >\n> > > I'll fix these small issues when applying.\n> > >\n> > > > +           if (!gst_registry_scan_path(registry, path.c_str())) {\n> > > > +                   g_printerr(\"Failed to add plugin to registry\\n\");\n> > > > +                   gst_deinit();\n> > > > +                   return TestFail;\n> > > > +           }\n> > > > +\n> > > > +           /* Create the elements */\n> > > > +           libcameraSrc_ = gst_element_factory_make(\"libcamerasrc\",\n> > \"libcamera\");\n> > > > +           convert0_ = gst_element_factory_make(\"videoconvert\",\n> > \"convert0\");\n> > > > +           sink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > > > +\n> > > > +           /* Create the empty pipeline_ */\n> > > > +           pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > > +\n> > > > +           if (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_)\n> > {\n> > > > +                   g_printerr(\"Not all elements could be created.\n> > %p.%p.%p.%p\\n\",\n> > > > +                              pipeline_, convert0_, sink0_,\n> > libcameraSrc_);\n> > > > +                   if (pipeline_)\n> > > > +                           gst_object_unref(pipeline_);\n> > > > +                   if (convert0_)\n> > > > +                           gst_object_unref(convert0_);\n> > > > +                   if (sink0_)\n> > > > +                           gst_object_unref(sink0_);\n> > > > +                   if (libcameraSrc_)\n> > > > +                           gst_object_unref(libcameraSrc_);\n> > > > +                   gst_deinit();\n> > > > +\n> > > > +                   return TestFail;\n> > > > +           }\n> > > > +\n> > > > +           return TestPass;\n> > > > +   }\n> > > > +\n> > > > +   void cleanup() override\n> > > > +   {\n> > > > +           gst_object_unref(pipeline_);\n> > > > +           gst_deinit();\n> > > > +   }\n> > > > +\n> > > > +   int run() override\n> > > > +   {\n> > > > +           GstStateChangeReturn ret;\n> > > > +           g_autoptr(GstBus) bus;\n> > > > +           g_autoptr(GstMessage) msg;\n> >\n> > I've also had to initialize those two variables to nullptr, to fix\n> >\n> > In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n> >                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n> >                  from /usr/include/glib-2.0/glib/galloca.h:32,\n> >                  from /usr/include/glib-2.0/glib.h:30,\n> >                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n> >                  from\n> > ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> > /usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int\n> > GstreamerSingleStreamTest::run()’:\n> > /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used\n> > uninitialized in this function [-Werror=maybe-uninitialized]\n> >  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }\n> >                                               \\\n> >       |       ^~\n> > ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note: ‘msg’\n> > was declared here\n> >   108 |   g_autoptr(GstMessage) msg;\n> >       |                         ^~~\n> >\n> > when cross-compiling for ARM.\n> >\n> > > > +\n> > > > +           /* Build the pipeline */\n> > > > +           gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,\n> > convert0_, sink0_, NULL);\n> > > > +           if (gst_element_link_many(libcameraSrc_, convert0_,\n> > sink0_, NULL) != TRUE) {\n> > > > +                   g_printerr(\"Elements could not be linked.\\n\");\n> > > > +                   return TestFail;\n> > > > +           }\n> > > > +\n> > > > +           /* Start playing */\n> > > > +           ret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > > > +           if (ret == GST_STATE_CHANGE_FAILURE) {\n> > > > +                   g_printerr(\"Unable to set the pipeline to the\n> > playing state.\\n\");\n> > > > +                   return TestFail;\n> > > > +           }\n> > > > +\n> > > > +           /* Wait until error or EOS or timeout after 2 seconds */\n> > > > +           GstClockTime timeout = 2000000000;\n> > > > +           bus = gst_element_get_bus(pipeline_);\n> > > > +           msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > > +\n> > GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > > +           gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > > +\n> > > > +           /* Parse error message */\n> > > > +           if (msg == NULL)\n> > > > +                   return TestPass;\n> > > > +\n> > > > +           switch (GST_MESSAGE_TYPE(msg)) {\n> > > > +           case GST_MESSAGE_ERROR:\n> > > > +                   gstreamer_print_error(msg);\n> > > > +                   break;\n> > > > +           case GST_MESSAGE_EOS:\n> > > > +                   g_print(\"End-Of-Stream reached.\\n\");\n> > > > +                   break;\n> > > > +           default:\n> > > > +                   g_printerr(\"Unexpected message received.\\n\");\n> > > > +                   break;\n> > > > +           }\n> > > > +\n> > > > +           return TestFail;\n> > > > +   }\n> > > > +\n> > > > +private:\n> > > > +   void gstreamer_print_error(GstMessage *msg)\n> > > > +   {\n> > > > +           GError *err;\n> > > > +           gchar *debug_info;\n> > > > +\n> > > > +           gst_message_parse_error(msg, &err, &debug_info);\n> > > > +           g_printerr(\"Error received from element %s: %s\\n\",\n> > > > +                      GST_OBJECT_NAME(msg->src), err->message);\n> > > > +           g_printerr(\"Debugging information: %s\\n\",\n> > > > +                      debug_info ? debug_info : \"none\");\n> > > > +           g_clear_error(&err);\n> > > > +           g_free(debug_info);\n> > > > +   }\n> > > > +\n> > > > +   GstElement *pipeline_;\n> > > > +   GstElement *libcameraSrc_;\n> > > > +   GstElement *convert0_;\n> > > > +   GstElement *sink0_;\n> > > > +};\n> > > > +\n> > > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > > > new file mode 100644\n> > > > index 00000000..b99aa0da\n> > > > --- /dev/null\n> > > > +++ b/test/gstreamer/meson.build\n> > > > @@ -0,0 +1,19 @@\n> > > > +# SPDX-License-Identifier: CC0-1.0\n> > > > +\n> > > > +if not gst_enabled\n> > > > +    subdir_done()\n> > > > +endif\n> > > > +\n> > > > +gstreamer_tests = [\n> > > > +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> > > > +]\n> > > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > > +\n> > > > +foreach t : gstreamer_tests\n> > > > +    exe = executable(t[0], t[1],\n> > > > +                     dependencies : [libcamera_private,\n> > gstreamer_dep],\n> > > > +                     link_with : test_libraries,\n> > > > +                     include_directories : test_includes_internal)\n> > > > +\n> > > > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > > > +endforeach\n> > > > diff --git a/test/meson.build b/test/meson.build\n> > > > index 3bceb5df..d0466f17 100644\n> > > > --- a/test/meson.build\n> > > > +++ b/test/meson.build\n> > > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > > >\n> > > >  subdir('camera')\n> > > >  subdir('controls')\n> > > > +subdir('gstreamer')\n> > > >  subdir('ipa')\n> > > >  subdir('ipc')\n> > > >  subdir('log')","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 952E2C3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 14:42:56 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1B8526888F;\n\tFri, 13 Aug 2021 16:42:56 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 04F3E687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 16:42:55 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 779908F;\n\tFri, 13 Aug 2021 16:42:54 +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=\"J+N688AY\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628865774;\n\tbh=jNEuFQoBChfDoeimvk6iZjMfEvJwnJZi/M6QS7+c6g8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=J+N688AYBqKSmUsmkUXRwZSbgTRaS5z96+OGX7L0/tP8jtAdQGnccgtJbcbHEizTX\n\tJnNecn/BhqRFt0bd9S/9RtnrJqq8ts8iBxHQdJ+/kQOc7sl0vcqPZQ7xtMW1ay4YXF\n\tM9MDNc03Xreg817vAcieckic0ui9oI07tQjcyAvI=","Date":"Fri, 13 Aug 2021 17:42:49 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Message-ID":"<YRaE6ZWNywis/St7@pendragon.ideasonboard.com>","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>\n\t<CACGrz-Mah_5pauFehpDdiPLPMcgOD1r302UkrUqktoByQNsa8w@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<CACGrz-Mah_5pauFehpDdiPLPMcgOD1r302UkrUqktoByQNsa8w@mail.gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18781,"web_url":"https://patchwork.libcamera.org/comment/18781/","msgid":"<CACGrz-M77Fk=hZYFKztXmZgVJE52OEnaBJRwP_UZmdb=vhnpLg@mail.gmail.com>","date":"2021-08-13T16:44:09","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":85,"url":"https://patchwork.libcamera.org/api/people/85/","name":"Vedant Paranjape","email":"vedantparanjape160201@gmail.com"},"content":"Hi Laurent,\nI was unable to reproduce the issue with address sanitizer.\n\nSteps I followed:\n1) meson --reconfigure build -Db_sanitize=address\n2) ninja -C build test\n\nRegards,\nVedant\n\nOn Fri, Aug 13, 2021 at 8:07 PM Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> On Fri, Aug 13, 2021 at 05:04:01PM +0300, Laurent Pinchart wrote:\n> > On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > > Hi Vedant,\n> > >\n> > > Thank you for the patch.\n> > >\n> > > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > > > This patch adds a test to test if single stream using\n> > > > libcamera's gstreamer element works.\n> > > >\n> > > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> > > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > > ---\n> > > >  .../gstreamer_single_stream_test.cpp          | 153\n> ++++++++++++++++++\n> > > >  test/gstreamer/meson.build                    |  19 +++\n> > > >  test/meson.build                              |   1 +\n> > > >  3 files changed, 173 insertions(+)\n> > > >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> > > >  create mode 100644 test/gstreamer/meson.build\n> > > >\n> > > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp\n> b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > new file mode 100644\n> > > > index 00000000..eecd3274\n> > > > --- /dev/null\n> > > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > @@ -0,0 +1,153 @@\n> > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > > +/*\n> > > > + * Copyright (C) 2021, Vedant Paranjape\n> > > > + *\n> > > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > > + */\n> > > > +\n> > > > +#include <iostream>\n> > > > +\n> > > > +#include <libcamera/base/utils.h>\n> > > > +\n> > > > +#include <gst/gst.h>\n> > > > +\n> > > > +#include \"test.h\"\n> > > > +\n> > > > +using namespace std;\n> > > > +\n> > > > +class GstreamerSingleStreamTest : public Test\n> > > > +{\n> > > > +protected:\n> > > > + int init() override\n> > > > + {\n> > > > +         /* Initialize GStreamer */\n> > > > +         GError *errInit = nullptr;\n> > > > +         if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > > +                 g_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > > > +                            errInit ? errInit->message : \"unknown\n> error\");\n> > > > +                 if (errInit)\n> > > > +                         g_error_free(errInit);\n> > > > +\n> > > > +                 return TestFail;\n> > > > +         }\n> > > > +\n> > > > +         /*\n> > > > +         * Remove the system libcamera plugin, if any, and add the\n> > > > +         * plugin from the build directory.\n> > > > +         */\n> > >\n> > > Missing space before *\n> > >\n> > > > +         GstRegistry *registry = gst_registry_get();\n> > > > +         GstPlugin *plugin = gst_registry_lookup(registry,\n> \"libgstlibcamera.so\");\n> > > > +         if (plugin) {\n> > > > +                 gst_registry_remove_plugin(registry, plugin);\n> > > > +                 gst_object_unref(plugin);\n> > > > +         }\n> > > > +\n> > >\n> > > Extra blank spaces at the end of the line.\n> > >\n> > > > +         std::string path =\n> std::string(libcamera::utils::libcameraBuildPath()\n> > > > +                                 + \"src/gstreamer\");\n> > >\n> > > No need for calling the std::string constructor explictly,\n> > > libcamera::utils::libcameraBuildPath() returns an std::string and the\n> > > result of the operator+() call is also an std::string.\n> > >\n> > > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > > libcamera::utils::libcameraBuildPath().\n> > >\n> > > I'll fix these small issues when applying.\n> > >\n> > > > +         if (!gst_registry_scan_path(registry, path.c_str())) {\n> > > > +                 g_printerr(\"Failed to add plugin to registry\\n\");\n> > > > +                 gst_deinit();\n> > > > +                 return TestFail;\n> > > > +         }\n> > > > +\n> > > > +         /* Create the elements */\n> > > > +         libcameraSrc_ = gst_element_factory_make(\"libcamerasrc\",\n> \"libcamera\");\n>\n> And now I'm getting a failure here :-( When compiling with gcc, and with\n> the meson b_sanitize option set to 'address', this call returns null.\n>\n> 10/64 libcamera:gstreamer / single_stream_test\n>  FAIL            0.48s   exit status 1\n> >>> MALLOC_PERTURB_=101\n> build/x86-gcc-11.1.0/test/gstreamer/single_stream_test\n> ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> ✀\n> ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> stderr:\n> ==14992==ASan runtime does not come first in initial library list; you\n> should either link runtime to your application or manually preload it with\n> LD_PRELOAD.\n> ==14993==ASan runtime does not come first in initial library list; you\n> should either link runtime to your application or manually preload it with\n> LD_PRELOAD.\n> Not all elements could be created.\n> 0x6290000241f0.0x61a000019950.0x61a00001a670.(nil)\n>\n> =================================================================\n> ==14990==ERROR: LeakSanitizer: detected memory leaks\n>\n> Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n>     #0 0x7f9daade1ac7 in __interceptor_malloc\n> /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n>     #1 0x7f9da776a938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n>\n> SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n>\n> ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n>\n> 11/64 libcamera:ipa / ipa_module_test\n> OK              0.08s\n>\n> Interestingly, if I run the test with\n>\n> LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libasan.so.6\n> ./test/gstreamer/single_stream_test\n>\n> then is runs fine:\n>\n> [25:59:46.412146534] [18711]  INFO IPAManager ipa_manager.cpp:138\n> libcamera is not installed. Adding '[...]/build/x86-gcc-11.1.0/src/ipa' to\n> the IPA search path\n> [25:59:46.413634330] [18711]  INFO Camera camera_manager.cpp:294 libcamera\n> v0.0.0+2881-24c1e91b-dirty (2021-08-13T17:24:37+03:00)\n> [25:59:46.663097368] [18714]  WARN CameraSensorProperties\n> camera_sensor_properties.cpp:123 No static properties available for 'Sensor\n> B'\n> [25:59:46.663129122] [18714]  WARN CameraSensorProperties\n> camera_sensor_properties.cpp:125 Please consider updating the camera sensor\n> properties database\n> [25:59:46.663156409] [18714]  WARN CameraSensor camera_sensor.cpp:403\n> 'Sensor B': Failed to retrieve the camera location\n> [25:59:46.664891182] [18714]  INFO IPAProxy ipa_proxy.cpp:130 libcamera is\n> not installed. Loading IPA configuration from '[...]/src/ipa/vimc/data'\n> [25:59:46.680563655] [18715]  INFO Camera camera.cpp:870 configuring\n> streams: (0) 160x120-YUYV\n>\n> =================================================================\n> ==18711==ERROR: LeakSanitizer: detected memory leaks\n>\n> Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n>     #0 0x7effa6393ac7 in __interceptor_malloc\n> /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n>     #1 0x7effa57be938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n>\n> SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n>\n> The leak is a known glib issue, caught by valgrind too, so I'm not\n> worried about it. The test failing to run is however a blocker.\n>\n> Vedant, can you reproduce the failure with the address sanitizer ?\n>\n> > > > +         convert0_ = gst_element_factory_make(\"videoconvert\",\n> \"convert0\");\n> > > > +         sink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > > > +\n> > > > +         /* Create the empty pipeline_ */\n> > > > +         pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > > +\n> > > > +         if (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_)\n> {\n> > > > +                 g_printerr(\"Not all elements could be created.\n> %p.%p.%p.%p\\n\",\n> > > > +                            pipeline_, convert0_, sink0_,\n> libcameraSrc_);\n> > > > +                 if (pipeline_)\n> > > > +                         gst_object_unref(pipeline_);\n> > > > +                 if (convert0_)\n> > > > +                         gst_object_unref(convert0_);\n> > > > +                 if (sink0_)\n> > > > +                         gst_object_unref(sink0_);\n> > > > +                 if (libcameraSrc_)\n> > > > +                         gst_object_unref(libcameraSrc_);\n> > > > +                 gst_deinit();\n> > > > +\n> > > > +                 return TestFail;\n> > > > +         }\n> > > > +\n> > > > +         return TestPass;\n> > > > + }\n> > > > +\n> > > > + void cleanup() override\n> > > > + {\n> > > > +         gst_object_unref(pipeline_);\n> > > > +         gst_deinit();\n> > > > + }\n> > > > +\n> > > > + int run() override\n> > > > + {\n> > > > +         GstStateChangeReturn ret;\n> > > > +         g_autoptr(GstBus) bus;\n> > > > +         g_autoptr(GstMessage) msg;\n> >\n> > I've also had to initialize those two variables to nullptr, to fix\n> >\n> > In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n> >                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n> >                  from /usr/include/glib-2.0/glib/galloca.h:32,\n> >                  from /usr/include/glib-2.0/glib.h:30,\n> >                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n> >                  from\n> ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> > /usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int\n> GstreamerSingleStreamTest::run()’:\n> > /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used\n> uninitialized in this function [-Werror=maybe-uninitialized]\n> >  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }\n>                                                 \\\n> >       |       ^~\n> > ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note:\n> ‘msg’ was declared here\n> >   108 |   g_autoptr(GstMessage) msg;\n> >       |                         ^~~\n> >\n> > when cross-compiling for ARM.\n> >\n> > > > +\n> > > > +         /* Build the pipeline */\n> > > > +         gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,\n> convert0_, sink0_, NULL);\n> > > > +         if (gst_element_link_many(libcameraSrc_, convert0_,\n> sink0_, NULL) != TRUE) {\n> > > > +                 g_printerr(\"Elements could not be linked.\\n\");\n> > > > +                 return TestFail;\n> > > > +         }\n> > > > +\n> > > > +         /* Start playing */\n> > > > +         ret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > > > +         if (ret == GST_STATE_CHANGE_FAILURE) {\n> > > > +                 g_printerr(\"Unable to set the pipeline to the\n> playing state.\\n\");\n> > > > +                 return TestFail;\n> > > > +         }\n> > > > +\n> > > > +         /* Wait until error or EOS or timeout after 2 seconds */\n> > > > +         GstClockTime timeout = 2000000000;\n> > > > +         bus = gst_element_get_bus(pipeline_);\n> > > > +         msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > > +\n> GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > > +         gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > > +\n> > > > +         /* Parse error message */\n> > > > +         if (msg == NULL)\n> > > > +                 return TestPass;\n> > > > +\n> > > > +         switch (GST_MESSAGE_TYPE(msg)) {\n> > > > +         case GST_MESSAGE_ERROR:\n> > > > +                 gstreamer_print_error(msg);\n> > > > +                 break;\n> > > > +         case GST_MESSAGE_EOS:\n> > > > +                 g_print(\"End-Of-Stream reached.\\n\");\n> > > > +                 break;\n> > > > +         default:\n> > > > +                 g_printerr(\"Unexpected message received.\\n\");\n> > > > +                 break;\n> > > > +         }\n> > > > +\n> > > > +         return TestFail;\n> > > > + }\n> > > > +\n> > > > +private:\n> > > > + void gstreamer_print_error(GstMessage *msg)\n> > > > + {\n> > > > +         GError *err;\n> > > > +         gchar *debug_info;\n> > > > +\n> > > > +         gst_message_parse_error(msg, &err, &debug_info);\n> > > > +         g_printerr(\"Error received from element %s: %s\\n\",\n> > > > +                    GST_OBJECT_NAME(msg->src), err->message);\n> > > > +         g_printerr(\"Debugging information: %s\\n\",\n> > > > +                    debug_info ? debug_info : \"none\");\n> > > > +         g_clear_error(&err);\n> > > > +         g_free(debug_info);\n> > > > + }\n> > > > +\n> > > > + GstElement *pipeline_;\n> > > > + GstElement *libcameraSrc_;\n> > > > + GstElement *convert0_;\n> > > > + GstElement *sink0_;\n> > > > +};\n> > > > +\n> > > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > > > new file mode 100644\n> > > > index 00000000..b99aa0da\n> > > > --- /dev/null\n> > > > +++ b/test/gstreamer/meson.build\n> > > > @@ -0,0 +1,19 @@\n> > > > +# SPDX-License-Identifier: CC0-1.0\n> > > > +\n> > > > +if not gst_enabled\n> > > > +    subdir_done()\n> > > > +endif\n> > > > +\n> > > > +gstreamer_tests = [\n> > > > +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> > > > +]\n> > > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > > +\n> > > > +foreach t : gstreamer_tests\n> > > > +    exe = executable(t[0], t[1],\n> > > > +                     dependencies : [libcamera_private,\n> gstreamer_dep],\n> > > > +                     link_with : test_libraries,\n> > > > +                     include_directories : test_includes_internal)\n> > > > +\n> > > > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > > > +endforeach\n> > > > diff --git a/test/meson.build b/test/meson.build\n> > > > index 3bceb5df..d0466f17 100644\n> > > > --- a/test/meson.build\n> > > > +++ b/test/meson.build\n> > > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > > >\n> > > >  subdir('camera')\n> > > >  subdir('controls')\n> > > > +subdir('gstreamer')\n> > > >  subdir('ipa')\n> > > >  subdir('ipc')\n> > > >  subdir('log')\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\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 D1A99C3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 16:44:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2951868891;\n\tFri, 13 Aug 2021 18:44:24 +0200 (CEST)","from mail-yb1-xb2e.google.com (mail-yb1-xb2e.google.com\n\t[IPv6:2607:f8b0:4864:20::b2e])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 42881687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 18:44:23 +0200 (CEST)","by mail-yb1-xb2e.google.com with SMTP id a93so19975709ybi.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 09:44:23 -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=\"S+yyFTzz\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=Lv83BVItrXYTOIGg7aVGtqx9ZRZi8gUk7wMSWZkC9Qs=;\n\tb=S+yyFTzzbr4QDcrjk33XyEqtVxNLbHpwDqt6CpeMJj5LXQ85Y1hP3vfi3hY5QboIEq\n\tEqjhUL4/kTuX9M20oaWhXbfbxk3wEpxawPbOfndyxr5B7ktrIpQzQ/AreKjE4faEvsNr\n\tOujfFC8uhPFDNm8vu92ryCJ5gLznGsSlUGa/EzNQrJG5PDF+xCPP4XwpvZ/jhivfZS4g\n\tDY8LEsl899q4gVRaAqDM3glLNtglPgFdGADGrwH040FIz1c/dQv8E57no7TrUTWT3LcW\n\tCwEgbTM145eC8yhfp7pwZniHAUO05zHxJWeOCgUIzY2lSs8wkuS0OBTNRle2bRDaHfgE\n\t6ZAw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=Lv83BVItrXYTOIGg7aVGtqx9ZRZi8gUk7wMSWZkC9Qs=;\n\tb=ggeK5KbnGXR/902/khp7O+Q6axkGz+4kdlEE8z7i95BhB5zjFk0psNJpIZ2f/VJ1K3\n\tRTFqVex4GUxN988LIkjIyattyYJkyq5/Y6XCZ6RjS2vttJXa4enj1Bi/VdNejkRtiqnk\n\tit4Y3o/Fvv1012kO5/goF5gOcnfojlyuap8fBdtKc/vXdeOOqSBTQDMz0+WDAAZFPZzB\n\t+Wn/xCMbj7Tf7sZG2ZW/FIR/k3jVWK/xQimKTXhb5N7ifmvKdK5kmQxV6ZxE+QkIvSI7\n\tLB3ofr72cByLcXTfAPdR+yqPyYrypTXqBX9IlFARJpM7jXhGR9RXsmQAZlvWqbcaf/jO\n\t+HmA==","X-Gm-Message-State":"AOAM5332CSmLSyYequLf6/hDephxikwKGwZnpTNe2KK4dDVcA3CO483e\n\tUsH9Q88YTg/xWF3v8JsaDLCxfnz8a5NGNCKBDhJZC4OfykA=","X-Google-Smtp-Source":"ABdhPJwMBva3pOb98exK/WHav4I8yMnGyKE0KaZfPPQtrCubLVmpUdKWwxWUiFWcdKU/kTRQv5/UakQja17FIFd1mbA=","X-Received":"by 2002:a25:d084:: with SMTP id\n\th126mr4132887ybg.175.1628873061791; \n\tFri, 13 Aug 2021 09:44:21 -0700 (PDT)","MIME-Version":"1.0","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>\n\t<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>","In-Reply-To":"<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>","From":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Date":"Fri, 13 Aug 2021 22:14:09 +0530","Message-ID":"<CACGrz-M77Fk=hZYFKztXmZgVJE52OEnaBJRwP_UZmdb=vhnpLg@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"0000000000003b7a5b05c973900c\"","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18782,"web_url":"https://patchwork.libcamera.org/comment/18782/","msgid":"<YRakwqBu6+7e/23X@pendragon.ideasonboard.com>","date":"2021-08-13T16:58:42","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Vedant,\n\nOn Fri, Aug 13, 2021 at 10:14:09PM +0530, Vedant Paranjape wrote:\n> Hi Laurent,\n> I was unable to reproduce the issue with address sanitizer.\n> \n> Steps I followed:\n> 1) meson --reconfigure build -Db_sanitize=address\n> 2) ninja -C build test\n\nWhat's the full output of the gstreamer test when you run it manually ?\n\n> On Fri, Aug 13, 2021 at 8:07 PM Laurent Pinchart wrote:\n> > On Fri, Aug 13, 2021 at 05:04:01PM +0300, Laurent Pinchart wrote:\n> > > On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > > > Hi Vedant,\n> > > >\n> > > > Thank you for the patch.\n> > > >\n> > > > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > > > > This patch adds a test to test if single stream using\n> > > > > libcamera's gstreamer element works.\n> > > > >\n> > > > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>\n> > > > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > > > ---\n> > > > >  .../gstreamer_single_stream_test.cpp          | 153\n> > ++++++++++++++++++\n> > > > >  test/gstreamer/meson.build                    |  19 +++\n> > > > >  test/meson.build                              |   1 +\n> > > > >  3 files changed, 173 insertions(+)\n> > > > >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > >  create mode 100644 test/gstreamer/meson.build\n> > > > >\n> > > > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp\n> > b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > new file mode 100644\n> > > > > index 00000000..eecd3274\n> > > > > --- /dev/null\n> > > > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > @@ -0,0 +1,153 @@\n> > > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > > > +/*\n> > > > > + * Copyright (C) 2021, Vedant Paranjape\n> > > > > + *\n> > > > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > > > + */\n> > > > > +\n> > > > > +#include <iostream>\n> > > > > +\n> > > > > +#include <libcamera/base/utils.h>\n> > > > > +\n> > > > > +#include <gst/gst.h>\n> > > > > +\n> > > > > +#include \"test.h\"\n> > > > > +\n> > > > > +using namespace std;\n> > > > > +\n> > > > > +class GstreamerSingleStreamTest : public Test\n> > > > > +{\n> > > > > +protected:\n> > > > > + int init() override\n> > > > > + {\n> > > > > +         /* Initialize GStreamer */\n> > > > > +         GError *errInit = nullptr;\n> > > > > +         if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > > > +                 g_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > > > > +                            errInit ? errInit->message : \"unknown\n> > error\");\n> > > > > +                 if (errInit)\n> > > > > +                         g_error_free(errInit);\n> > > > > +\n> > > > > +                 return TestFail;\n> > > > > +         }\n> > > > > +\n> > > > > +         /*\n> > > > > +         * Remove the system libcamera plugin, if any, and add the\n> > > > > +         * plugin from the build directory.\n> > > > > +         */\n> > > >\n> > > > Missing space before *\n> > > >\n> > > > > +         GstRegistry *registry = gst_registry_get();\n> > > > > +         GstPlugin *plugin = gst_registry_lookup(registry,\n> > \"libgstlibcamera.so\");\n> > > > > +         if (plugin) {\n> > > > > +                 gst_registry_remove_plugin(registry, plugin);\n> > > > > +                 gst_object_unref(plugin);\n> > > > > +         }\n> > > > > +\n> > > >\n> > > > Extra blank spaces at the end of the line.\n> > > >\n> > > > > +         std::string path =\n> > std::string(libcamera::utils::libcameraBuildPath()\n> > > > > +                                 + \"src/gstreamer\");\n> > > >\n> > > > No need for calling the std::string constructor explictly,\n> > > > libcamera::utils::libcameraBuildPath() returns an std::string and the\n> > > > result of the operator+() call is also an std::string.\n> > > >\n> > > > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > > > libcamera::utils::libcameraBuildPath().\n> > > >\n> > > > I'll fix these small issues when applying.\n> > > >\n> > > > > +         if (!gst_registry_scan_path(registry, path.c_str())) {\n> > > > > +                 g_printerr(\"Failed to add plugin to registry\\n\");\n> > > > > +                 gst_deinit();\n> > > > > +                 return TestFail;\n> > > > > +         }\n> > > > > +\n> > > > > +         /* Create the elements */\n> > > > > +         libcameraSrc_ = gst_element_factory_make(\"libcamerasrc\",\n> > \"libcamera\");\n> >\n> > And now I'm getting a failure here :-( When compiling with gcc, and with\n> > the meson b_sanitize option set to 'address', this call returns null.\n> >\n> > 10/64 libcamera:gstreamer / single_stream_test\n> >  FAIL            0.48s   exit status 1\n> > >>> MALLOC_PERTURB_=101\n> > build/x86-gcc-11.1.0/test/gstreamer/single_stream_test\n> > ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > ✀\n> > ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > stderr:\n> > ==14992==ASan runtime does not come first in initial library list; you\n> > should either link runtime to your application or manually preload it with\n> > LD_PRELOAD.\n> > ==14993==ASan runtime does not come first in initial library list; you\n> > should either link runtime to your application or manually preload it with\n> > LD_PRELOAD.\n> > Not all elements could be created.\n> > 0x6290000241f0.0x61a000019950.0x61a00001a670.(nil)\n> >\n> > =================================================================\n> > ==14990==ERROR: LeakSanitizer: detected memory leaks\n> >\n> > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> >     #0 0x7f9daade1ac7 in __interceptor_malloc\n> > /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> >     #1 0x7f9da776a938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> >\n> > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> >\n> > ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> >\n> > 11/64 libcamera:ipa / ipa_module_test\n> > OK              0.08s\n> >\n> > Interestingly, if I run the test with\n> >\n> > LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libasan.so.6\n> > ./test/gstreamer/single_stream_test\n> >\n> > then is runs fine:\n> >\n> > [25:59:46.412146534] [18711]  INFO IPAManager ipa_manager.cpp:138\n> > libcamera is not installed. Adding '[...]/build/x86-gcc-11.1.0/src/ipa' to\n> > the IPA search path\n> > [25:59:46.413634330] [18711]  INFO Camera camera_manager.cpp:294 libcamera\n> > v0.0.0+2881-24c1e91b-dirty (2021-08-13T17:24:37+03:00)\n> > [25:59:46.663097368] [18714]  WARN CameraSensorProperties\n> > camera_sensor_properties.cpp:123 No static properties available for 'Sensor\n> > B'\n> > [25:59:46.663129122] [18714]  WARN CameraSensorProperties\n> > camera_sensor_properties.cpp:125 Please consider updating the camera sensor\n> > properties database\n> > [25:59:46.663156409] [18714]  WARN CameraSensor camera_sensor.cpp:403\n> > 'Sensor B': Failed to retrieve the camera location\n> > [25:59:46.664891182] [18714]  INFO IPAProxy ipa_proxy.cpp:130 libcamera is\n> > not installed. Loading IPA configuration from '[...]/src/ipa/vimc/data'\n> > [25:59:46.680563655] [18715]  INFO Camera camera.cpp:870 configuring\n> > streams: (0) 160x120-YUYV\n> >\n> > =================================================================\n> > ==18711==ERROR: LeakSanitizer: detected memory leaks\n> >\n> > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> >     #0 0x7effa6393ac7 in __interceptor_malloc\n> > /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> >     #1 0x7effa57be938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> >\n> > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> >\n> > The leak is a known glib issue, caught by valgrind too, so I'm not\n> > worried about it. The test failing to run is however a blocker.\n> >\n> > Vedant, can you reproduce the failure with the address sanitizer ?\n> >\n> > > > > +         convert0_ = gst_element_factory_make(\"videoconvert\",\n> > \"convert0\");\n> > > > > +         sink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > > > > +\n> > > > > +         /* Create the empty pipeline_ */\n> > > > > +         pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > > > +\n> > > > > +         if (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_)\n> > {\n> > > > > +                 g_printerr(\"Not all elements could be created.\n> > %p.%p.%p.%p\\n\",\n> > > > > +                            pipeline_, convert0_, sink0_,\n> > libcameraSrc_);\n> > > > > +                 if (pipeline_)\n> > > > > +                         gst_object_unref(pipeline_);\n> > > > > +                 if (convert0_)\n> > > > > +                         gst_object_unref(convert0_);\n> > > > > +                 if (sink0_)\n> > > > > +                         gst_object_unref(sink0_);\n> > > > > +                 if (libcameraSrc_)\n> > > > > +                         gst_object_unref(libcameraSrc_);\n> > > > > +                 gst_deinit();\n> > > > > +\n> > > > > +                 return TestFail;\n> > > > > +         }\n> > > > > +\n> > > > > +         return TestPass;\n> > > > > + }\n> > > > > +\n> > > > > + void cleanup() override\n> > > > > + {\n> > > > > +         gst_object_unref(pipeline_);\n> > > > > +         gst_deinit();\n> > > > > + }\n> > > > > +\n> > > > > + int run() override\n> > > > > + {\n> > > > > +         GstStateChangeReturn ret;\n> > > > > +         g_autoptr(GstBus) bus;\n> > > > > +         g_autoptr(GstMessage) msg;\n> > >\n> > > I've also had to initialize those two variables to nullptr, to fix\n> > >\n> > > In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n> > >                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n> > >                  from /usr/include/glib-2.0/glib/galloca.h:32,\n> > >                  from /usr/include/glib-2.0/glib.h:30,\n> > >                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n> > >                  from\n> > ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> > > /usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int\n> > GstreamerSingleStreamTest::run()’:\n> > > /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used\n> > uninitialized in this function [-Werror=maybe-uninitialized]\n> > >  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }\n> >                                                 \\\n> > >       |       ^~\n> > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note:\n> > ‘msg’ was declared here\n> > >   108 |   g_autoptr(GstMessage) msg;\n> > >       |                         ^~~\n> > >\n> > > when cross-compiling for ARM.\n> > >\n> > > > > +\n> > > > > +         /* Build the pipeline */\n> > > > > +         gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,\n> > convert0_, sink0_, NULL);\n> > > > > +         if (gst_element_link_many(libcameraSrc_, convert0_,\n> > sink0_, NULL) != TRUE) {\n> > > > > +                 g_printerr(\"Elements could not be linked.\\n\");\n> > > > > +                 return TestFail;\n> > > > > +         }\n> > > > > +\n> > > > > +         /* Start playing */\n> > > > > +         ret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > > > > +         if (ret == GST_STATE_CHANGE_FAILURE) {\n> > > > > +                 g_printerr(\"Unable to set the pipeline to the\n> > playing state.\\n\");\n> > > > > +                 return TestFail;\n> > > > > +         }\n> > > > > +\n> > > > > +         /* Wait until error or EOS or timeout after 2 seconds */\n> > > > > +         GstClockTime timeout = 2000000000;\n> > > > > +         bus = gst_element_get_bus(pipeline_);\n> > > > > +         msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > > > +\n> > GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > > > +         gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > > > +\n> > > > > +         /* Parse error message */\n> > > > > +         if (msg == NULL)\n> > > > > +                 return TestPass;\n> > > > > +\n> > > > > +         switch (GST_MESSAGE_TYPE(msg)) {\n> > > > > +         case GST_MESSAGE_ERROR:\n> > > > > +                 gstreamer_print_error(msg);\n> > > > > +                 break;\n> > > > > +         case GST_MESSAGE_EOS:\n> > > > > +                 g_print(\"End-Of-Stream reached.\\n\");\n> > > > > +                 break;\n> > > > > +         default:\n> > > > > +                 g_printerr(\"Unexpected message received.\\n\");\n> > > > > +                 break;\n> > > > > +         }\n> > > > > +\n> > > > > +         return TestFail;\n> > > > > + }\n> > > > > +\n> > > > > +private:\n> > > > > + void gstreamer_print_error(GstMessage *msg)\n> > > > > + {\n> > > > > +         GError *err;\n> > > > > +         gchar *debug_info;\n> > > > > +\n> > > > > +         gst_message_parse_error(msg, &err, &debug_info);\n> > > > > +         g_printerr(\"Error received from element %s: %s\\n\",\n> > > > > +                    GST_OBJECT_NAME(msg->src), err->message);\n> > > > > +         g_printerr(\"Debugging information: %s\\n\",\n> > > > > +                    debug_info ? debug_info : \"none\");\n> > > > > +         g_clear_error(&err);\n> > > > > +         g_free(debug_info);\n> > > > > + }\n> > > > > +\n> > > > > + GstElement *pipeline_;\n> > > > > + GstElement *libcameraSrc_;\n> > > > > + GstElement *convert0_;\n> > > > > + GstElement *sink0_;\n> > > > > +};\n> > > > > +\n> > > > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > > > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > > > > new file mode 100644\n> > > > > index 00000000..b99aa0da\n> > > > > --- /dev/null\n> > > > > +++ b/test/gstreamer/meson.build\n> > > > > @@ -0,0 +1,19 @@\n> > > > > +# SPDX-License-Identifier: CC0-1.0\n> > > > > +\n> > > > > +if not gst_enabled\n> > > > > +    subdir_done()\n> > > > > +endif\n> > > > > +\n> > > > > +gstreamer_tests = [\n> > > > > +    ['single_stream_test',   'gstreamer_single_stream_test.cpp'],\n> > > > > +]\n> > > > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > > > +\n> > > > > +foreach t : gstreamer_tests\n> > > > > +    exe = executable(t[0], t[1],\n> > > > > +                     dependencies : [libcamera_private,\n> > gstreamer_dep],\n> > > > > +                     link_with : test_libraries,\n> > > > > +                     include_directories : test_includes_internal)\n> > > > > +\n> > > > > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > > > > +endforeach\n> > > > > diff --git a/test/meson.build b/test/meson.build\n> > > > > index 3bceb5df..d0466f17 100644\n> > > > > --- a/test/meson.build\n> > > > > +++ b/test/meson.build\n> > > > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > > > >\n> > > > >  subdir('camera')\n> > > > >  subdir('controls')\n> > > > > +subdir('gstreamer')\n> > > > >  subdir('ipa')\n> > > > >  subdir('ipc')\n> > > > >  subdir('log')","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 7A1BFBD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 16:58:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EFD1E6888D;\n\tFri, 13 Aug 2021 18:58:49 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1BE99687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 18:58:48 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 80D694A1;\n\tFri, 13 Aug 2021 18:58:47 +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=\"Sw4FWt70\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628873927;\n\tbh=hgAwC/SOK68thom/gkVrdvJDzlyS5v3z3p2DowoQnys=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Sw4FWt70x2SxbFfjJAXcF14Cc7gkKFkZFqgUDLIimsWHc5IAg3joQRUN51tfuYlLa\n\t4ba/EJn4fdk9L5XeYjSqUyFkl080x8u85td93vsG3n3sKBQzOQIVTAf4gcjegBE4cZ\n\tsHblAoFUGcWEHKSHaoaLwC1bh1epaJykgpgDkmtc=","Date":"Fri, 13 Aug 2021 19:58:42 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Message-ID":"<YRakwqBu6+7e/23X@pendragon.ideasonboard.com>","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>\n\t<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>\n\t<CACGrz-M77Fk=hZYFKztXmZgVJE52OEnaBJRwP_UZmdb=vhnpLg@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<CACGrz-M77Fk=hZYFKztXmZgVJE52OEnaBJRwP_UZmdb=vhnpLg@mail.gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18783,"web_url":"https://patchwork.libcamera.org/comment/18783/","msgid":"<CACGrz-MGFx7Ju9tkpH+pmdWwNUc8aFtKrC-VuXKirXhFjWnn2A@mail.gmail.com>","date":"2021-08-13T17:01:43","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":85,"url":"https://patchwork.libcamera.org/api/people/85/","name":"Vedant Paranjape","email":"vedantparanjape160201@gmail.com"},"content":"Hi Laurent,\n\nvedant@veware ~/Programming/contributing/libcamera$\n./build/test/gstreamer/single_stream_test\n                                           ✹ ✭wip-negotiation\n[11:45:45.304648653] [243629]  INFO IPAManager ipa_manager.cpp:138\nlibcamera is not installed. Adding\n'/home/vedant/Programming/contributing/libcamera/build/src/ipa' to the IPA\nsearch path\n[11:45:45.306046376] [243629]  INFO Camera camera_manager.cpp:294 libcamera\nv0.0.0+2877-e3edb100-dirty (2021-08-13T22:11:47+05:30)\n[11:45:45.319737506] [243632]  INFO Camera camera.cpp:870 configuring\nstreams: (0) 640x360-YUYV\n\nOn Fri, Aug 13, 2021 at 10:28 PM Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> Hi Vedant,\n>\n> On Fri, Aug 13, 2021 at 10:14:09PM +0530, Vedant Paranjape wrote:\n> > Hi Laurent,\n> > I was unable to reproduce the issue with address sanitizer.\n> >\n> > Steps I followed:\n> > 1) meson --reconfigure build -Db_sanitize=address\n> > 2) ninja -C build test\n>\n> What's the full output of the gstreamer test when you run it manually ?\n>\n> > On Fri, Aug 13, 2021 at 8:07 PM Laurent Pinchart wrote:\n> > > On Fri, Aug 13, 2021 at 05:04:01PM +0300, Laurent Pinchart wrote:\n> > > > On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > > > > Hi Vedant,\n> > > > >\n> > > > > Thank you for the patch.\n> > > > >\n> > > > > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > > > > > This patch adds a test to test if single stream using\n> > > > > > libcamera's gstreamer element works.\n> > > > > >\n> > > > > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com\n> >\n> > > > > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > > > > ---\n> > > > > >  .../gstreamer_single_stream_test.cpp          | 153\n> > > ++++++++++++++++++\n> > > > > >  test/gstreamer/meson.build                    |  19 +++\n> > > > > >  test/meson.build                              |   1 +\n> > > > > >  3 files changed, 173 insertions(+)\n> > > > > >  create mode 100644\n> test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > >  create mode 100644 test/gstreamer/meson.build\n> > > > > >\n> > > > > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > new file mode 100644\n> > > > > > index 00000000..eecd3274\n> > > > > > --- /dev/null\n> > > > > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > @@ -0,0 +1,153 @@\n> > > > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > > > > +/*\n> > > > > > + * Copyright (C) 2021, Vedant Paranjape\n> > > > > > + *\n> > > > > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > > > > + */\n> > > > > > +\n> > > > > > +#include <iostream>\n> > > > > > +\n> > > > > > +#include <libcamera/base/utils.h>\n> > > > > > +\n> > > > > > +#include <gst/gst.h>\n> > > > > > +\n> > > > > > +#include \"test.h\"\n> > > > > > +\n> > > > > > +using namespace std;\n> > > > > > +\n> > > > > > +class GstreamerSingleStreamTest : public Test\n> > > > > > +{\n> > > > > > +protected:\n> > > > > > + int init() override\n> > > > > > + {\n> > > > > > +         /* Initialize GStreamer */\n> > > > > > +         GError *errInit = nullptr;\n> > > > > > +         if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > > > > +                 g_printerr(\"Could not initialize GStreamer:\n> %s\\n\",\n> > > > > > +                            errInit ? errInit->message :\n> \"unknown\n> > > error\");\n> > > > > > +                 if (errInit)\n> > > > > > +                         g_error_free(errInit);\n> > > > > > +\n> > > > > > +                 return TestFail;\n> > > > > > +         }\n> > > > > > +\n> > > > > > +         /*\n> > > > > > +         * Remove the system libcamera plugin, if any, and add\n> the\n> > > > > > +         * plugin from the build directory.\n> > > > > > +         */\n> > > > >\n> > > > > Missing space before *\n> > > > >\n> > > > > > +         GstRegistry *registry = gst_registry_get();\n> > > > > > +         GstPlugin *plugin = gst_registry_lookup(registry,\n> > > \"libgstlibcamera.so\");\n> > > > > > +         if (plugin) {\n> > > > > > +                 gst_registry_remove_plugin(registry, plugin);\n> > > > > > +                 gst_object_unref(plugin);\n> > > > > > +         }\n> > > > > > +\n> > > > >\n> > > > > Extra blank spaces at the end of the line.\n> > > > >\n> > > > > > +         std::string path =\n> > > std::string(libcamera::utils::libcameraBuildPath()\n> > > > > > +                                 + \"src/gstreamer\");\n> > > > >\n> > > > > No need for calling the std::string constructor explictly,\n> > > > > libcamera::utils::libcameraBuildPath() returns an std::string and\n> the\n> > > > > result of the operator+() call is also an std::string.\n> > > > >\n> > > > > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > > > > libcamera::utils::libcameraBuildPath().\n> > > > >\n> > > > > I'll fix these small issues when applying.\n> > > > >\n> > > > > > +         if (!gst_registry_scan_path(registry, path.c_str())) {\n> > > > > > +                 g_printerr(\"Failed to add plugin to\n> registry\\n\");\n> > > > > > +                 gst_deinit();\n> > > > > > +                 return TestFail;\n> > > > > > +         }\n> > > > > > +\n> > > > > > +         /* Create the elements */\n> > > > > > +         libcameraSrc_ =\n> gst_element_factory_make(\"libcamerasrc\",\n> > > \"libcamera\");\n> > >\n> > > And now I'm getting a failure here :-( When compiling with gcc, and\n> with\n> > > the meson b_sanitize option set to 'address', this call returns null.\n> > >\n> > > 10/64 libcamera:gstreamer / single_stream_test\n> > >  FAIL            0.48s   exit status 1\n> > > >>> MALLOC_PERTURB_=101\n> > > build/x86-gcc-11.1.0/test/gstreamer/single_stream_test\n> > >\n> ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > > ✀\n> > >\n> ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > > stderr:\n> > > ==14992==ASan runtime does not come first in initial library list; you\n> > > should either link runtime to your application or manually preload it\n> with\n> > > LD_PRELOAD.\n> > > ==14993==ASan runtime does not come first in initial library list; you\n> > > should either link runtime to your application or manually preload it\n> with\n> > > LD_PRELOAD.\n> > > Not all elements could be created.\n> > > 0x6290000241f0.0x61a000019950.0x61a00001a670.(nil)\n> > >\n> > > =================================================================\n> > > ==14990==ERROR: LeakSanitizer: detected memory leaks\n> > >\n> > > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> > >     #0 0x7f9daade1ac7 in __interceptor_malloc\n> > >\n> /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> > >     #1 0x7f9da776a938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> > >\n> > > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> > >\n> > >\n> ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > >\n> > > 11/64 libcamera:ipa / ipa_module_test\n> > > OK              0.08s\n> > >\n> > > Interestingly, if I run the test with\n> > >\n> > > LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libasan.so.6\n> > > ./test/gstreamer/single_stream_test\n> > >\n> > > then is runs fine:\n> > >\n> > > [25:59:46.412146534] [18711]  INFO IPAManager ipa_manager.cpp:138\n> > > libcamera is not installed. Adding\n> '[...]/build/x86-gcc-11.1.0/src/ipa' to\n> > > the IPA search path\n> > > [25:59:46.413634330] [18711]  INFO Camera camera_manager.cpp:294\n> libcamera\n> > > v0.0.0+2881-24c1e91b-dirty (2021-08-13T17:24:37+03:00)\n> > > [25:59:46.663097368] [18714]  WARN CameraSensorProperties\n> > > camera_sensor_properties.cpp:123 No static properties available for\n> 'Sensor\n> > > B'\n> > > [25:59:46.663129122] [18714]  WARN CameraSensorProperties\n> > > camera_sensor_properties.cpp:125 Please consider updating the camera\n> sensor\n> > > properties database\n> > > [25:59:46.663156409] [18714]  WARN CameraSensor camera_sensor.cpp:403\n> > > 'Sensor B': Failed to retrieve the camera location\n> > > [25:59:46.664891182] [18714]  INFO IPAProxy ipa_proxy.cpp:130\n> libcamera is\n> > > not installed. Loading IPA configuration from '[...]/src/ipa/vimc/data'\n> > > [25:59:46.680563655] [18715]  INFO Camera camera.cpp:870 configuring\n> > > streams: (0) 160x120-YUYV\n> > >\n> > > =================================================================\n> > > ==18711==ERROR: LeakSanitizer: detected memory leaks\n> > >\n> > > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> > >     #0 0x7effa6393ac7 in __interceptor_malloc\n> > >\n> /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> > >     #1 0x7effa57be938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> > >\n> > > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> > >\n> > > The leak is a known glib issue, caught by valgrind too, so I'm not\n> > > worried about it. The test failing to run is however a blocker.\n> > >\n> > > Vedant, can you reproduce the failure with the address sanitizer ?\n> > >\n> > > > > > +         convert0_ = gst_element_factory_make(\"videoconvert\",\n> > > \"convert0\");\n> > > > > > +         sink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > > > > > +\n> > > > > > +         /* Create the empty pipeline_ */\n> > > > > > +         pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > > > > +\n> > > > > > +         if (!pipeline_ || !convert0_ || !sink0_ ||\n> !libcameraSrc_)\n> > > {\n> > > > > > +                 g_printerr(\"Not all elements could be created.\n> > > %p.%p.%p.%p\\n\",\n> > > > > > +                            pipeline_, convert0_, sink0_,\n> > > libcameraSrc_);\n> > > > > > +                 if (pipeline_)\n> > > > > > +                         gst_object_unref(pipeline_);\n> > > > > > +                 if (convert0_)\n> > > > > > +                         gst_object_unref(convert0_);\n> > > > > > +                 if (sink0_)\n> > > > > > +                         gst_object_unref(sink0_);\n> > > > > > +                 if (libcameraSrc_)\n> > > > > > +                         gst_object_unref(libcameraSrc_);\n> > > > > > +                 gst_deinit();\n> > > > > > +\n> > > > > > +                 return TestFail;\n> > > > > > +         }\n> > > > > > +\n> > > > > > +         return TestPass;\n> > > > > > + }\n> > > > > > +\n> > > > > > + void cleanup() override\n> > > > > > + {\n> > > > > > +         gst_object_unref(pipeline_);\n> > > > > > +         gst_deinit();\n> > > > > > + }\n> > > > > > +\n> > > > > > + int run() override\n> > > > > > + {\n> > > > > > +         GstStateChangeReturn ret;\n> > > > > > +         g_autoptr(GstBus) bus;\n> > > > > > +         g_autoptr(GstMessage) msg;\n> > > >\n> > > > I've also had to initialize those two variables to nullptr, to fix\n> > > >\n> > > > In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n> > > >                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n> > > >                  from /usr/include/glib-2.0/glib/galloca.h:32,\n> > > >                  from /usr/include/glib-2.0/glib.h:30,\n> > > >                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n> > > >                  from\n> > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> > > > /usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int\n> > > GstreamerSingleStreamTest::run()’:\n> > > > /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used\n> > > uninitialized in this function [-Werror=maybe-uninitialized]\n> > > >  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }\n> > >                                                 \\\n> > > >       |       ^~\n> > > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note:\n> > > ‘msg’ was declared here\n> > > >   108 |   g_autoptr(GstMessage) msg;\n> > > >       |                         ^~~\n> > > >\n> > > > when cross-compiling for ARM.\n> > > >\n> > > > > > +\n> > > > > > +         /* Build the pipeline */\n> > > > > > +         gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_,\n> > > convert0_, sink0_, NULL);\n> > > > > > +         if (gst_element_link_many(libcameraSrc_, convert0_,\n> > > sink0_, NULL) != TRUE) {\n> > > > > > +                 g_printerr(\"Elements could not be linked.\\n\");\n> > > > > > +                 return TestFail;\n> > > > > > +         }\n> > > > > > +\n> > > > > > +         /* Start playing */\n> > > > > > +         ret = gst_element_set_state(pipeline_,\n> GST_STATE_PLAYING);\n> > > > > > +         if (ret == GST_STATE_CHANGE_FAILURE) {\n> > > > > > +                 g_printerr(\"Unable to set the pipeline to the\n> > > playing state.\\n\");\n> > > > > > +                 return TestFail;\n> > > > > > +         }\n> > > > > > +\n> > > > > > +         /* Wait until error or EOS or timeout after 2 seconds\n> */\n> > > > > > +         GstClockTime timeout = 2000000000;\n> > > > > > +         bus = gst_element_get_bus(pipeline_);\n> > > > > > +         msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > > > > +\n> > > GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > > > > +         gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > > > > +\n> > > > > > +         /* Parse error message */\n> > > > > > +         if (msg == NULL)\n> > > > > > +                 return TestPass;\n> > > > > > +\n> > > > > > +         switch (GST_MESSAGE_TYPE(msg)) {\n> > > > > > +         case GST_MESSAGE_ERROR:\n> > > > > > +                 gstreamer_print_error(msg);\n> > > > > > +                 break;\n> > > > > > +         case GST_MESSAGE_EOS:\n> > > > > > +                 g_print(\"End-Of-Stream reached.\\n\");\n> > > > > > +                 break;\n> > > > > > +         default:\n> > > > > > +                 g_printerr(\"Unexpected message received.\\n\");\n> > > > > > +                 break;\n> > > > > > +         }\n> > > > > > +\n> > > > > > +         return TestFail;\n> > > > > > + }\n> > > > > > +\n> > > > > > +private:\n> > > > > > + void gstreamer_print_error(GstMessage *msg)\n> > > > > > + {\n> > > > > > +         GError *err;\n> > > > > > +         gchar *debug_info;\n> > > > > > +\n> > > > > > +         gst_message_parse_error(msg, &err, &debug_info);\n> > > > > > +         g_printerr(\"Error received from element %s: %s\\n\",\n> > > > > > +                    GST_OBJECT_NAME(msg->src), err->message);\n> > > > > > +         g_printerr(\"Debugging information: %s\\n\",\n> > > > > > +                    debug_info ? debug_info : \"none\");\n> > > > > > +         g_clear_error(&err);\n> > > > > > +         g_free(debug_info);\n> > > > > > + }\n> > > > > > +\n> > > > > > + GstElement *pipeline_;\n> > > > > > + GstElement *libcameraSrc_;\n> > > > > > + GstElement *convert0_;\n> > > > > > + GstElement *sink0_;\n> > > > > > +};\n> > > > > > +\n> > > > > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > > > > diff --git a/test/gstreamer/meson.build\n> b/test/gstreamer/meson.build\n> > > > > > new file mode 100644\n> > > > > > index 00000000..b99aa0da\n> > > > > > --- /dev/null\n> > > > > > +++ b/test/gstreamer/meson.build\n> > > > > > @@ -0,0 +1,19 @@\n> > > > > > +# SPDX-License-Identifier: CC0-1.0\n> > > > > > +\n> > > > > > +if not gst_enabled\n> > > > > > +    subdir_done()\n> > > > > > +endif\n> > > > > > +\n> > > > > > +gstreamer_tests = [\n> > > > > > +    ['single_stream_test',\n>  'gstreamer_single_stream_test.cpp'],\n> > > > > > +]\n> > > > > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > > > > +\n> > > > > > +foreach t : gstreamer_tests\n> > > > > > +    exe = executable(t[0], t[1],\n> > > > > > +                     dependencies : [libcamera_private,\n> > > gstreamer_dep],\n> > > > > > +                     link_with : test_libraries,\n> > > > > > +                     include_directories :\n> test_includes_internal)\n> > > > > > +\n> > > > > > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > > > > > +endforeach\n> > > > > > diff --git a/test/meson.build b/test/meson.build\n> > > > > > index 3bceb5df..d0466f17 100644\n> > > > > > --- a/test/meson.build\n> > > > > > +++ b/test/meson.build\n> > > > > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > > > > >\n> > > > > >  subdir('camera')\n> > > > > >  subdir('controls')\n> > > > > > +subdir('gstreamer')\n> > > > > >  subdir('ipa')\n> > > > > >  subdir('ipc')\n> > > > > >  subdir('log')\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\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 23D25C3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 17:01:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8CAF168891;\n\tFri, 13 Aug 2021 19:01:57 +0200 (CEST)","from mail-yb1-xb2d.google.com (mail-yb1-xb2d.google.com\n\t[IPv6:2607:f8b0:4864:20::b2d])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9BAD4687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 19:01:56 +0200 (CEST)","by mail-yb1-xb2d.google.com with SMTP id p4so20067504yba.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 10:01:56 -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=\"Jd7MATds\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=gZmRFA0/Z6gLOqi2DEEXZm2kaZ5HG1eQ7CBAqd/IXWQ=;\n\tb=Jd7MATdsSzp7V4G4bBre2uIYLiE50EwpccyHbvbKTCdJkBxDnY3rAKLu7IoHXtvS7q\n\tsXE2SR7IdCTDIRvsbGnodii2qM46xIOT9YIX5390FVIOWBVxHJPwUkkOxP29Y+WRluwj\n\tEtgQVyoYS1W+4/MSNaiaWVt6EK07kYTSnAzBTew9S0VN3gNrxrNgl424TUJ55ocw4xto\n\tuL4nQBLFamGjtfFVKSXrT4+GBr3F6XzmtbtfmBtcK07wc6IGPfKH9ujqOh5uoTgh+UIX\n\ta81OBEHNt/q/ZwhQEvRLR6ezVsuyr10lK9aJPA15AFjX1TSJWurL/PuCnlO6If9Lig6H\n\tsnAA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=gZmRFA0/Z6gLOqi2DEEXZm2kaZ5HG1eQ7CBAqd/IXWQ=;\n\tb=N3TklwZCrmuucy2yZXwXBP2WbAsFtz5YaSlh8M17JqsxM0lluxsazN8cs3CczkxX1d\n\tHLPvRhR+UpAZEvZrtwt+qDZ8qVdkmdaOO0QUz1QbenGl7kbVH7nVd544fvgaaP5B61pX\n\tGCw5Z4QikTuGiUCnwCMIe11r1Mp3KEQcs7/0OgnoFS0WzSrBzqpXeirJZmUVE+rBSWPq\n\tNMl3N68rm6sXXCn5Fzd3zVZ4xY6yNzOsMeas1dBn7fgXLKWZ2UJ+7wW6TehsMpA6zk+q\n\tK7Q3eBuaMygNYQyZRQ6BCvi9dlGYEuJ8U1m+FOB01txLZ6lJG33Yqpx9QIJzDuiCvA1R\n\t8c/Q==","X-Gm-Message-State":"AOAM530bKvLqlY5bZWu6ej2Zfpzltd9oZqhVPabeOb6CMErIjobXZrj3\n\tHrJGknn2ic/bXFCNnm0QzuWMPUk8VRUDD4FKskg=","X-Google-Smtp-Source":"ABdhPJxAvdGKIfxJ0PfgboEfkSIqLBnwKIH4wtjKO05DEccAHFGxX8LK4T1mkHghvoyCoyAnPdgw/7PLswZbhGX218Q=","X-Received":"by 2002:a25:37cf:: with SMTP id\n\te198mr4030387yba.223.1628874115335; \n\tFri, 13 Aug 2021 10:01:55 -0700 (PDT)","MIME-Version":"1.0","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>\n\t<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>\n\t<CACGrz-M77Fk=hZYFKztXmZgVJE52OEnaBJRwP_UZmdb=vhnpLg@mail.gmail.com>\n\t<YRakwqBu6+7e/23X@pendragon.ideasonboard.com>","In-Reply-To":"<YRakwqBu6+7e/23X@pendragon.ideasonboard.com>","From":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Date":"Fri, 13 Aug 2021 22:31:43 +0530","Message-ID":"<CACGrz-MGFx7Ju9tkpH+pmdWwNUc8aFtKrC-VuXKirXhFjWnn2A@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"00000000000007499805c973cfd4\"","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18784,"web_url":"https://patchwork.libcamera.org/comment/18784/","msgid":"<YRa8ZzMTI/t1s8lD@pendragon.ideasonboard.com>","date":"2021-08-13T18:39:35","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Vedant,\n\nOn Fri, Aug 13, 2021 at 10:31:43PM +0530, Vedant Paranjape wrote:\n> Hi Laurent,\n> \n> vedant@veware ~/Programming/contributing/libcamera$\n> ./build/test/gstreamer/single_stream_test\n>                                            ✹ ✭wip-negotiation\n> [11:45:45.304648653] [243629]  INFO IPAManager ipa_manager.cpp:138 libcamera is not installed. Adding '/home/vedant/Programming/contributing/libcamera/build/src/ipa' to the IPA search path\n> [11:45:45.306046376] [243629]  INFO Camera camera_manager.cpp:294 libcamera v0.0.0+2877-e3edb100-dirty (2021-08-13T22:11:47+05:30)\n> [11:45:45.319737506] [243632]  INFO Camera camera.cpp:870 configuring streams: (0) 640x360-YUYV\n\nAs discussed on IRC, that didn't have asan enabled.\n\nRunning\n\nLD_DEBUG=libs ./test/gstreamer/single_stream_test\n\ngives useful information. GStreamer spawns a new process,\ngst-plugin-scanner, to locate the libcamerasrc plugin. As gstreamer is\ncompiled without asan, the gst-plugin-scanner process has lots of\nlibraries loaded when it dlopen()s the plugin .so, which results in a\nfailure in the asan library order sanity check, producing the messages\n\n==24099==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n==24100==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n\nI'm getting the exact same two messages when running gst-inspect or\ngst-launch. However,\n\ngst-launch-1.0 --gst-plugin-path=$(pwd)/src/gstreamer/ libcamerasrc ! videoconvert ! fakesink\n\ndoesn't fail. There may thus be something we're doing wrong, or at least\nin a different way.\n\n> On Fri, Aug 13, 2021 at 10:28 PM Laurent Pinchart wrote:\n> > On Fri, Aug 13, 2021 at 10:14:09PM +0530, Vedant Paranjape wrote:\n> > > Hi Laurent,\n> > > I was unable to reproduce the issue with address sanitizer.\n> > >\n> > > Steps I followed:\n> > > 1) meson --reconfigure build -Db_sanitize=address\n> > > 2) ninja -C build test\n> >\n> > What's the full output of the gstreamer test when you run it manually ?\n> >\n> > > On Fri, Aug 13, 2021 at 8:07 PM Laurent Pinchart wrote:\n> > > > On Fri, Aug 13, 2021 at 05:04:01PM +0300, Laurent Pinchart wrote:\n> > > > > On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > > > > > Hi Vedant,\n> > > > > >\n> > > > > > Thank you for the patch.\n> > > > > >\n> > > > > > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > > > > > > This patch adds a test to test if single stream using\n> > > > > > > libcamera's gstreamer element works.\n> > > > > > >\n> > > > > > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com\n> > > > > > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > > > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > > > > > ---\n> > > > > > >  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n> > > > > > >  test/gstreamer/meson.build                    |  19 +++\n> > > > > > >  test/meson.build                              |   1 +\n> > > > > > >  3 files changed, 173 insertions(+)\n> > > > > > >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > >  create mode 100644 test/gstreamer/meson.build\n> > > > > > >\n> > > > > > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > > new file mode 100644\n> > > > > > > index 00000000..eecd3274\n> > > > > > > --- /dev/null\n> > > > > > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > > @@ -0,0 +1,153 @@\n> > > > > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > > > > > +/*\n> > > > > > > + * Copyright (C) 2021, Vedant Paranjape\n> > > > > > > + *\n> > > > > > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > > > > > + */\n> > > > > > > +\n> > > > > > > +#include <iostream>\n> > > > > > > +\n> > > > > > > +#include <libcamera/base/utils.h>\n> > > > > > > +\n> > > > > > > +#include <gst/gst.h>\n> > > > > > > +\n> > > > > > > +#include \"test.h\"\n> > > > > > > +\n> > > > > > > +using namespace std;\n> > > > > > > +\n> > > > > > > +class GstreamerSingleStreamTest : public Test\n> > > > > > > +{\n> > > > > > > +protected:\n> > > > > > > + int init() override\n> > > > > > > + {\n> > > > > > > +         /* Initialize GStreamer */\n> > > > > > > +         GError *errInit = nullptr;\n> > > > > > > +         if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > > > > > +                 g_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > > > > > > +                            errInit ? errInit->message : \"unknown error\");\n> > > > > > > +                 if (errInit)\n> > > > > > > +                         g_error_free(errInit);\n> > > > > > > +\n> > > > > > > +                 return TestFail;\n> > > > > > > +         }\n> > > > > > > +\n> > > > > > > +         /*\n> > > > > > > +         * Remove the system libcamera plugin, if any, and add the\n> > > > > > > +         * plugin from the build directory.\n> > > > > > > +         */\n> > > > > >\n> > > > > > Missing space before *\n> > > > > >\n> > > > > > > +         GstRegistry *registry = gst_registry_get();\n> > > > > > > +         GstPlugin *plugin = gst_registry_lookup(registry, \"libgstlibcamera.so\");\n> > > > > > > +         if (plugin) {\n> > > > > > > +                 gst_registry_remove_plugin(registry, plugin);\n> > > > > > > +                 gst_object_unref(plugin);\n> > > > > > > +         }\n> > > > > > > +\n> > > > > >\n> > > > > > Extra blank spaces at the end of the line.\n> > > > > >\n> > > > > > > +         std::string path = std::string(libcamera::utils::libcameraBuildPath()\n> > > > > > > +                                 + \"src/gstreamer\");\n> > > > > >\n> > > > > > No need for calling the std::string constructor explictly,\n> > > > > > libcamera::utils::libcameraBuildPath() returns an std::string and the\n> > > > > > result of the operator+() call is also an std::string.\n> > > > > >\n> > > > > > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > > > > > libcamera::utils::libcameraBuildPath().\n> > > > > >\n> > > > > > I'll fix these small issues when applying.\n> > > > > >\n> > > > > > > +         if (!gst_registry_scan_path(registry, path.c_str())) {\n> > > > > > > +                 g_printerr(\"Failed to add plugin to registry\\n\");\n> > > > > > > +                 gst_deinit();\n> > > > > > > +                 return TestFail;\n> > > > > > > +         }\n> > > > > > > +\n> > > > > > > +         /* Create the elements */\n> > > > > > > +         libcameraSrc_ = gst_element_factory_make(\"libcamerasrc\", \"libcamera\");\n> > > >\n> > > > And now I'm getting a failure here :-( When compiling with gcc, and with\n> > > > the meson b_sanitize option set to 'address', this call returns null.\n> > > >\n> > > > 10/64 libcamera:gstreamer / single_stream_test\n> > > >  FAIL            0.48s   exit status 1\n> > > > >>> MALLOC_PERTURB_=101\n> > > > build/x86-gcc-11.1.0/test/gstreamer/single_stream_test\n> > > > ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― ✀ ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > > > stderr:\n> > > > ==14992==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n> > > > ==14993==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n> > > > Not all elements could be created. 0x6290000241f0.0x61a000019950.0x61a00001a670.(nil)\n> > > >\n> > > > =================================================================\n> > > > ==14990==ERROR: LeakSanitizer: detected memory leaks\n> > > >\n> > > > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> > > >     #0 0x7f9daade1ac7 in __interceptor_malloc\n> > > > /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> > > >     #1 0x7f9da776a938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> > > >\n> > > > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> > > >\n> > > > ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > > >\n> > > > 11/64 libcamera:ipa / ipa_module_test\n> > > > OK              0.08s\n> > > >\n> > > > Interestingly, if I run the test with\n> > > >\n> > > > LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libasan.so.6\n> > > > ./test/gstreamer/single_stream_test\n> > > >\n> > > > then is runs fine:\n> > > >\n> > > > [25:59:46.412146534] [18711]  INFO IPAManager ipa_manager.cpp:138 libcamera is not installed. Adding '[...]/build/x86-gcc-11.1.0/src/ipa' to the IPA search path\n> > > > [25:59:46.413634330] [18711]  INFO Camera camera_manager.cpp:294 libcamera v0.0.0+2881-24c1e91b-dirty (2021-08-13T17:24:37+03:00)\n> > > > [25:59:46.663097368] [18714]  WARN CameraSensorProperties camera_sensor_properties.cpp:123 No static properties available for 'Sensor B'\n> > > > [25:59:46.663129122] [18714]  WARN CameraSensorProperties camera_sensor_properties.cpp:125 Please consider updating the camera sensor properties database\n> > > > [25:59:46.663156409] [18714]  WARN CameraSensor camera_sensor.cpp:403 'Sensor B': Failed to retrieve the camera location\n> > > > [25:59:46.664891182] [18714]  INFO IPAProxy ipa_proxy.cpp:130 libcamera is not installed. Loading IPA configuration from '[...]/src/ipa/vimc/data'\n> > > > [25:59:46.680563655] [18715]  INFO Camera camera.cpp:870 configuring streams: (0) 160x120-YUYV\n> > > >\n> > > > =================================================================\n> > > > ==18711==ERROR: LeakSanitizer: detected memory leaks\n> > > >\n> > > > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> > > >     #0 0x7effa6393ac7 in __interceptor_malloc\n> > > > /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> > > >     #1 0x7effa57be938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> > > >\n> > > > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> > > >\n> > > > The leak is a known glib issue, caught by valgrind too, so I'm not\n> > > > worried about it. The test failing to run is however a blocker.\n> > > >\n> > > > Vedant, can you reproduce the failure with the address sanitizer ?\n> > > >\n> > > > > > > +         convert0_ = gst_element_factory_make(\"videoconvert\", \"convert0\");\n> > > > > > > +         sink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > > > > > > +\n> > > > > > > +         /* Create the empty pipeline_ */\n> > > > > > > +         pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > > > > > +\n> > > > > > > +         if (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_) {\n> > > > > > > +                 g_printerr(\"Not all elements could be created. %p.%p.%p.%p\\n\",\n> > > > > > > +                            pipeline_, convert0_, sink0_, libcameraSrc_);\n> > > > > > > +                 if (pipeline_)\n> > > > > > > +                         gst_object_unref(pipeline_);\n> > > > > > > +                 if (convert0_)\n> > > > > > > +                         gst_object_unref(convert0_);\n> > > > > > > +                 if (sink0_)\n> > > > > > > +                         gst_object_unref(sink0_);\n> > > > > > > +                 if (libcameraSrc_)\n> > > > > > > +                         gst_object_unref(libcameraSrc_);\n> > > > > > > +                 gst_deinit();\n> > > > > > > +\n> > > > > > > +                 return TestFail;\n> > > > > > > +         }\n> > > > > > > +\n> > > > > > > +         return TestPass;\n> > > > > > > + }\n> > > > > > > +\n> > > > > > > + void cleanup() override\n> > > > > > > + {\n> > > > > > > +         gst_object_unref(pipeline_);\n> > > > > > > +         gst_deinit();\n> > > > > > > + }\n> > > > > > > +\n> > > > > > > + int run() override\n> > > > > > > + {\n> > > > > > > +         GstStateChangeReturn ret;\n> > > > > > > +         g_autoptr(GstBus) bus;\n> > > > > > > +         g_autoptr(GstMessage) msg;\n> > > > >\n> > > > > I've also had to initialize those two variables to nullptr, to fix\n> > > > >\n> > > > > In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n> > > > >                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n> > > > >                  from /usr/include/glib-2.0/glib/galloca.h:32,\n> > > > >                  from /usr/include/glib-2.0/glib.h:30,\n> > > > >                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n> > > > >                  from\n> > > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> > > > > /usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int GstreamerSingleStreamTest::run()’:\n> > > > > /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used uninitialized in this function [-Werror=maybe-uninitialized]\n> > > > >  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }\n> > > >                                                 \\\n> > > > >       |       ^~\n> > > > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note: ‘msg’ was declared here\n> > > > >   108 |   g_autoptr(GstMessage) msg;\n> > > > >       |                         ^~~\n> > > > >\n> > > > > when cross-compiling for ARM.\n> > > > >\n> > > > > > > +\n> > > > > > > +         /* Build the pipeline */\n> > > > > > > +         gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, convert0_, sink0_, NULL);\n> > > > > > > +         if (gst_element_link_many(libcameraSrc_, convert0_, sink0_, NULL) != TRUE) {\n> > > > > > > +                 g_printerr(\"Elements could not be linked.\\n\");\n> > > > > > > +                 return TestFail;\n> > > > > > > +         }\n> > > > > > > +\n> > > > > > > +         /* Start playing */\n> > > > > > > +         ret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > > > > > > +         if (ret == GST_STATE_CHANGE_FAILURE) {\n> > > > > > > +                 g_printerr(\"Unable to set the pipeline to the playing state.\\n\");\n> > > > > > > +                 return TestFail;\n> > > > > > > +         }\n> > > > > > > +\n> > > > > > > +         /* Wait until error or EOS or timeout after 2 seconds */\n> > > > > > > +         GstClockTime timeout = 2000000000;\n> > > > > > > +         bus = gst_element_get_bus(pipeline_);\n> > > > > > > +         msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > > > > > +                                          GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > > > > > +         gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > > > > > +\n> > > > > > > +         /* Parse error message */\n> > > > > > > +         if (msg == NULL)\n> > > > > > > +                 return TestPass;\n> > > > > > > +\n> > > > > > > +         switch (GST_MESSAGE_TYPE(msg)) {\n> > > > > > > +         case GST_MESSAGE_ERROR:\n> > > > > > > +                 gstreamer_print_error(msg);\n> > > > > > > +                 break;\n> > > > > > > +         case GST_MESSAGE_EOS:\n> > > > > > > +                 g_print(\"End-Of-Stream reached.\\n\");\n> > > > > > > +                 break;\n> > > > > > > +         default:\n> > > > > > > +                 g_printerr(\"Unexpected message received.\\n\");\n> > > > > > > +                 break;\n> > > > > > > +         }\n> > > > > > > +\n> > > > > > > +         return TestFail;\n> > > > > > > + }\n> > > > > > > +\n> > > > > > > +private:\n> > > > > > > + void gstreamer_print_error(GstMessage *msg)\n> > > > > > > + {\n> > > > > > > +         GError *err;\n> > > > > > > +         gchar *debug_info;\n> > > > > > > +\n> > > > > > > +         gst_message_parse_error(msg, &err, &debug_info);\n> > > > > > > +         g_printerr(\"Error received from element %s: %s\\n\",\n> > > > > > > +                    GST_OBJECT_NAME(msg->src), err->message);\n> > > > > > > +         g_printerr(\"Debugging information: %s\\n\",\n> > > > > > > +                    debug_info ? debug_info : \"none\");\n> > > > > > > +         g_clear_error(&err);\n> > > > > > > +         g_free(debug_info);\n> > > > > > > + }\n> > > > > > > +\n> > > > > > > + GstElement *pipeline_;\n> > > > > > > + GstElement *libcameraSrc_;\n> > > > > > > + GstElement *convert0_;\n> > > > > > > + GstElement *sink0_;\n> > > > > > > +};\n> > > > > > > +\n> > > > > > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > > > > > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > > > > > > new file mode 100644\n> > > > > > > index 00000000..b99aa0da\n> > > > > > > --- /dev/null\n> > > > > > > +++ b/test/gstreamer/meson.build\n> > > > > > > @@ -0,0 +1,19 @@\n> > > > > > > +# SPDX-License-Identifier: CC0-1.0\n> > > > > > > +\n> > > > > > > +if not gst_enabled\n> > > > > > > +    subdir_done()\n> > > > > > > +endif\n> > > > > > > +\n> > > > > > > +gstreamer_tests = [\n> > > > > > > +    ['single_stream_test',  'gstreamer_single_stream_test.cpp'],\n> > > > > > > +]\n> > > > > > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > > > > > +\n> > > > > > > +foreach t : gstreamer_tests\n> > > > > > > +    exe = executable(t[0], t[1],\n> > > > > > > +                     dependencies : [libcamera_private, gstreamer_dep],\n> > > > > > > +                     link_with : test_libraries,\n> > > > > > > +                     include_directories : test_includes_internal)\n> > > > > > > +\n> > > > > > > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > > > > > > +endforeach\n> > > > > > > diff --git a/test/meson.build b/test/meson.build\n> > > > > > > index 3bceb5df..d0466f17 100644\n> > > > > > > --- a/test/meson.build\n> > > > > > > +++ b/test/meson.build\n> > > > > > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > > > > > >\n> > > > > > >  subdir('camera')\n> > > > > > >  subdir('controls')\n> > > > > > > +subdir('gstreamer')\n> > > > > > >  subdir('ipa')\n> > > > > > >  subdir('ipc')\n> > > > > > >  subdir('log')","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 8E08ABD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 18:39:42 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 059B36888D;\n\tFri, 13 Aug 2021 20:39: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 79CA1687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 20:39:40 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E442EDD;\n\tFri, 13 Aug 2021 20:39: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=\"ZF0y0O7X\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628879980;\n\tbh=TC7lxOxQamyMpvDvnXhpe+MOu9WbykoNM69cXHTCtOI=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=ZF0y0O7XIXsnNUFHgIttiUdWpdnZheP8TRLjPXn3h70P4EHBk+shVF3kYGa2EwH0x\n\t0swfmKSXmRTXO/nqMlz1Mich6y6kUnM+IvkzuiRWkaSI7h3416SIBRx4TfN63P/FG5\n\t3Rxk8lRhIUAGTdMVhr57S1hWqBTtStKdl/Xkx0lE=","Date":"Fri, 13 Aug 2021 21:39:35 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Message-ID":"<YRa8ZzMTI/t1s8lD@pendragon.ideasonboard.com>","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>\n\t<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>\n\t<CACGrz-M77Fk=hZYFKztXmZgVJE52OEnaBJRwP_UZmdb=vhnpLg@mail.gmail.com>\n\t<YRakwqBu6+7e/23X@pendragon.ideasonboard.com>\n\t<CACGrz-MGFx7Ju9tkpH+pmdWwNUc8aFtKrC-VuXKirXhFjWnn2A@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<CACGrz-MGFx7Ju9tkpH+pmdWwNUc8aFtKrC-VuXKirXhFjWnn2A@mail.gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18785,"web_url":"https://patchwork.libcamera.org/comment/18785/","msgid":"<YRa9HRYmIHvn+dMn@pendragon.ideasonboard.com>","date":"2021-08-13T18:42:37","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Aug 13, 2021 at 09:39:36PM +0300, Laurent Pinchart wrote:\n> Hi Vedant,\n> \n> On Fri, Aug 13, 2021 at 10:31:43PM +0530, Vedant Paranjape wrote:\n> > Hi Laurent,\n> > \n> > vedant@veware ~/Programming/contributing/libcamera$\n> > ./build/test/gstreamer/single_stream_test\n> >                                            ✹ ✭wip-negotiation\n> > [11:45:45.304648653] [243629]  INFO IPAManager ipa_manager.cpp:138 libcamera is not installed. Adding '/home/vedant/Programming/contributing/libcamera/build/src/ipa' to the IPA search path\n> > [11:45:45.306046376] [243629]  INFO Camera camera_manager.cpp:294 libcamera v0.0.0+2877-e3edb100-dirty (2021-08-13T22:11:47+05:30)\n> > [11:45:45.319737506] [243632]  INFO Camera camera.cpp:870 configuring streams: (0) 640x360-YUYV\n> \n> As discussed on IRC, that didn't have asan enabled.\n> \n> Running\n> \n> LD_DEBUG=libs ./test/gstreamer/single_stream_test\n> \n> gives useful information. GStreamer spawns a new process,\n> gst-plugin-scanner, to locate the libcamerasrc plugin. As gstreamer is\n> compiled without asan, the gst-plugin-scanner process has lots of\n> libraries loaded when it dlopen()s the plugin .so, which results in a\n> failure in the asan library order sanity check, producing the messages\n> \n> ==24099==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n> ==24100==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n> \n> I'm getting the exact same two messages when running gst-inspect or\n> gst-launch. However,\n> \n> gst-launch-1.0 --gst-plugin-path=$(pwd)/src/gstreamer/ libcamerasrc ! videoconvert ! fakesink\n> \n> doesn't fail. There may thus be something we're doing wrong, or at least\n> in a different way.\n\nAnd replying to myself, the thing we're doing differently is loading the\ngstreamer plugin from the build directory instead of the system plugins\nlocation. When running the above command, gst-launch was using the\nsystem plugin.\n\n> > On Fri, Aug 13, 2021 at 10:28 PM Laurent Pinchart wrote:\n> > > On Fri, Aug 13, 2021 at 10:14:09PM +0530, Vedant Paranjape wrote:\n> > > > Hi Laurent,\n> > > > I was unable to reproduce the issue with address sanitizer.\n> > > >\n> > > > Steps I followed:\n> > > > 1) meson --reconfigure build -Db_sanitize=address\n> > > > 2) ninja -C build test\n> > >\n> > > What's the full output of the gstreamer test when you run it manually ?\n> > >\n> > > > On Fri, Aug 13, 2021 at 8:07 PM Laurent Pinchart wrote:\n> > > > > On Fri, Aug 13, 2021 at 05:04:01PM +0300, Laurent Pinchart wrote:\n> > > > > > On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > > > > > > Hi Vedant,\n> > > > > > >\n> > > > > > > Thank you for the patch.\n> > > > > > >\n> > > > > > > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape wrote:\n> > > > > > > > This patch adds a test to test if single stream using\n> > > > > > > > libcamera's gstreamer element works.\n> > > > > > > >\n> > > > > > > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com\n> > > > > > > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > > > > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > > > > > > ---\n> > > > > > > >  .../gstreamer_single_stream_test.cpp          | 153 ++++++++++++++++++\n> > > > > > > >  test/gstreamer/meson.build                    |  19 +++\n> > > > > > > >  test/meson.build                              |   1 +\n> > > > > > > >  3 files changed, 173 insertions(+)\n> > > > > > > >  create mode 100644 test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > > >  create mode 100644 test/gstreamer/meson.build\n> > > > > > > >\n> > > > > > > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > > > new file mode 100644\n> > > > > > > > index 00000000..eecd3274\n> > > > > > > > --- /dev/null\n> > > > > > > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > > > @@ -0,0 +1,153 @@\n> > > > > > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > > > > > > +/*\n> > > > > > > > + * Copyright (C) 2021, Vedant Paranjape\n> > > > > > > > + *\n> > > > > > > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > > > > > > + */\n> > > > > > > > +\n> > > > > > > > +#include <iostream>\n> > > > > > > > +\n> > > > > > > > +#include <libcamera/base/utils.h>\n> > > > > > > > +\n> > > > > > > > +#include <gst/gst.h>\n> > > > > > > > +\n> > > > > > > > +#include \"test.h\"\n> > > > > > > > +\n> > > > > > > > +using namespace std;\n> > > > > > > > +\n> > > > > > > > +class GstreamerSingleStreamTest : public Test\n> > > > > > > > +{\n> > > > > > > > +protected:\n> > > > > > > > + int init() override\n> > > > > > > > + {\n> > > > > > > > +         /* Initialize GStreamer */\n> > > > > > > > +         GError *errInit = nullptr;\n> > > > > > > > +         if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > > > > > > +                 g_printerr(\"Could not initialize GStreamer: %s\\n\",\n> > > > > > > > +                            errInit ? errInit->message : \"unknown error\");\n> > > > > > > > +                 if (errInit)\n> > > > > > > > +                         g_error_free(errInit);\n> > > > > > > > +\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         /*\n> > > > > > > > +         * Remove the system libcamera plugin, if any, and add the\n> > > > > > > > +         * plugin from the build directory.\n> > > > > > > > +         */\n> > > > > > >\n> > > > > > > Missing space before *\n> > > > > > >\n> > > > > > > > +         GstRegistry *registry = gst_registry_get();\n> > > > > > > > +         GstPlugin *plugin = gst_registry_lookup(registry, \"libgstlibcamera.so\");\n> > > > > > > > +         if (plugin) {\n> > > > > > > > +                 gst_registry_remove_plugin(registry, plugin);\n> > > > > > > > +                 gst_object_unref(plugin);\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > >\n> > > > > > > Extra blank spaces at the end of the line.\n> > > > > > >\n> > > > > > > > +         std::string path = std::string(libcamera::utils::libcameraBuildPath()\n> > > > > > > > +                                 + \"src/gstreamer\");\n> > > > > > >\n> > > > > > > No need for calling the std::string constructor explictly,\n> > > > > > > libcamera::utils::libcameraBuildPath() returns an std::string and the\n> > > > > > > result of the operator+() call is also an std::string.\n> > > > > > >\n> > > > > > > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > > > > > > libcamera::utils::libcameraBuildPath().\n> > > > > > >\n> > > > > > > I'll fix these small issues when applying.\n> > > > > > >\n> > > > > > > > +         if (!gst_registry_scan_path(registry, path.c_str())) {\n> > > > > > > > +                 g_printerr(\"Failed to add plugin to registry\\n\");\n> > > > > > > > +                 gst_deinit();\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         /* Create the elements */\n> > > > > > > > +         libcameraSrc_ = gst_element_factory_make(\"libcamerasrc\", \"libcamera\");\n> > > > >\n> > > > > And now I'm getting a failure here :-( When compiling with gcc, and with\n> > > > > the meson b_sanitize option set to 'address', this call returns null.\n> > > > >\n> > > > > 10/64 libcamera:gstreamer / single_stream_test\n> > > > >  FAIL            0.48s   exit status 1\n> > > > > >>> MALLOC_PERTURB_=101\n> > > > > build/x86-gcc-11.1.0/test/gstreamer/single_stream_test\n> > > > > ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― ✀ ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > > > > stderr:\n> > > > > ==14992==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n> > > > > ==14993==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.\n> > > > > Not all elements could be created. 0x6290000241f0.0x61a000019950.0x61a00001a670.(nil)\n> > > > >\n> > > > > =================================================================\n> > > > > ==14990==ERROR: LeakSanitizer: detected memory leaks\n> > > > >\n> > > > > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> > > > >     #0 0x7f9daade1ac7 in __interceptor_malloc\n> > > > > /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> > > > >     #1 0x7f9da776a938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> > > > >\n> > > > > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> > > > >\n> > > > > ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > > > >\n> > > > > 11/64 libcamera:ipa / ipa_module_test\n> > > > > OK              0.08s\n> > > > >\n> > > > > Interestingly, if I run the test with\n> > > > >\n> > > > > LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libasan.so.6\n> > > > > ./test/gstreamer/single_stream_test\n> > > > >\n> > > > > then is runs fine:\n> > > > >\n> > > > > [25:59:46.412146534] [18711]  INFO IPAManager ipa_manager.cpp:138 libcamera is not installed. Adding '[...]/build/x86-gcc-11.1.0/src/ipa' to the IPA search path\n> > > > > [25:59:46.413634330] [18711]  INFO Camera camera_manager.cpp:294 libcamera v0.0.0+2881-24c1e91b-dirty (2021-08-13T17:24:37+03:00)\n> > > > > [25:59:46.663097368] [18714]  WARN CameraSensorProperties camera_sensor_properties.cpp:123 No static properties available for 'Sensor B'\n> > > > > [25:59:46.663129122] [18714]  WARN CameraSensorProperties camera_sensor_properties.cpp:125 Please consider updating the camera sensor properties database\n> > > > > [25:59:46.663156409] [18714]  WARN CameraSensor camera_sensor.cpp:403 'Sensor B': Failed to retrieve the camera location\n> > > > > [25:59:46.664891182] [18714]  INFO IPAProxy ipa_proxy.cpp:130 libcamera is not installed. Loading IPA configuration from '[...]/src/ipa/vimc/data'\n> > > > > [25:59:46.680563655] [18715]  INFO Camera camera.cpp:870 configuring streams: (0) 160x120-YUYV\n> > > > >\n> > > > > =================================================================\n> > > > > ==18711==ERROR: LeakSanitizer: detected memory leaks\n> > > > >\n> > > > > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> > > > >     #0 0x7effa6393ac7 in __interceptor_malloc\n> > > > > /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> > > > >     #1 0x7effa57be938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> > > > >\n> > > > > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> > > > >\n> > > > > The leak is a known glib issue, caught by valgrind too, so I'm not\n> > > > > worried about it. The test failing to run is however a blocker.\n> > > > >\n> > > > > Vedant, can you reproduce the failure with the address sanitizer ?\n> > > > >\n> > > > > > > > +         convert0_ = gst_element_factory_make(\"videoconvert\", \"convert0\");\n> > > > > > > > +         sink0_ = gst_element_factory_make(\"fakesink\", \"sink0\");\n> > > > > > > > +\n> > > > > > > > +         /* Create the empty pipeline_ */\n> > > > > > > > +         pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > > > > > > +\n> > > > > > > > +         if (!pipeline_ || !convert0_ || !sink0_ || !libcameraSrc_) {\n> > > > > > > > +                 g_printerr(\"Not all elements could be created. %p.%p.%p.%p\\n\",\n> > > > > > > > +                            pipeline_, convert0_, sink0_, libcameraSrc_);\n> > > > > > > > +                 if (pipeline_)\n> > > > > > > > +                         gst_object_unref(pipeline_);\n> > > > > > > > +                 if (convert0_)\n> > > > > > > > +                         gst_object_unref(convert0_);\n> > > > > > > > +                 if (sink0_)\n> > > > > > > > +                         gst_object_unref(sink0_);\n> > > > > > > > +                 if (libcameraSrc_)\n> > > > > > > > +                         gst_object_unref(libcameraSrc_);\n> > > > > > > > +                 gst_deinit();\n> > > > > > > > +\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         return TestPass;\n> > > > > > > > + }\n> > > > > > > > +\n> > > > > > > > + void cleanup() override\n> > > > > > > > + {\n> > > > > > > > +         gst_object_unref(pipeline_);\n> > > > > > > > +         gst_deinit();\n> > > > > > > > + }\n> > > > > > > > +\n> > > > > > > > + int run() override\n> > > > > > > > + {\n> > > > > > > > +         GstStateChangeReturn ret;\n> > > > > > > > +         g_autoptr(GstBus) bus;\n> > > > > > > > +         g_autoptr(GstMessage) msg;\n> > > > > >\n> > > > > > I've also had to initialize those two variables to nullptr, to fix\n> > > > > >\n> > > > > > In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n> > > > > >                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n> > > > > >                  from /usr/include/glib-2.0/glib/galloca.h:32,\n> > > > > >                  from /usr/include/glib-2.0/glib.h:30,\n> > > > > >                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n> > > > > >                  from\n> > > > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> > > > > > /usr/include/glib-2.0/glib/gmacros.h: In member function ‘virtual int GstreamerSingleStreamTest::run()’:\n> > > > > > /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be used uninitialized in this function [-Werror=maybe-uninitialized]\n> > > > > >  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }\n> > > > >                                                 \\\n> > > > > >       |       ^~\n> > > > > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25: note: ‘msg’ was declared here\n> > > > > >   108 |   g_autoptr(GstMessage) msg;\n> > > > > >       |                         ^~~\n> > > > > >\n> > > > > > when cross-compiling for ARM.\n> > > > > >\n> > > > > > > > +\n> > > > > > > > +         /* Build the pipeline */\n> > > > > > > > +         gst_bin_add_many(GST_BIN(pipeline_), libcameraSrc_, convert0_, sink0_, NULL);\n> > > > > > > > +         if (gst_element_link_many(libcameraSrc_, convert0_, sink0_, NULL) != TRUE) {\n> > > > > > > > +                 g_printerr(\"Elements could not be linked.\\n\");\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         /* Start playing */\n> > > > > > > > +         ret = gst_element_set_state(pipeline_, GST_STATE_PLAYING);\n> > > > > > > > +         if (ret == GST_STATE_CHANGE_FAILURE) {\n> > > > > > > > +                 g_printerr(\"Unable to set the pipeline to the playing state.\\n\");\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         /* Wait until error or EOS or timeout after 2 seconds */\n> > > > > > > > +         GstClockTime timeout = 2000000000;\n> > > > > > > > +         bus = gst_element_get_bus(pipeline_);\n> > > > > > > > +         msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > > > > > > +                                          GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > > > > > > +         gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > > > > > > +\n> > > > > > > > +         /* Parse error message */\n> > > > > > > > +         if (msg == NULL)\n> > > > > > > > +                 return TestPass;\n> > > > > > > > +\n> > > > > > > > +         switch (GST_MESSAGE_TYPE(msg)) {\n> > > > > > > > +         case GST_MESSAGE_ERROR:\n> > > > > > > > +                 gstreamer_print_error(msg);\n> > > > > > > > +                 break;\n> > > > > > > > +         case GST_MESSAGE_EOS:\n> > > > > > > > +                 g_print(\"End-Of-Stream reached.\\n\");\n> > > > > > > > +                 break;\n> > > > > > > > +         default:\n> > > > > > > > +                 g_printerr(\"Unexpected message received.\\n\");\n> > > > > > > > +                 break;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         return TestFail;\n> > > > > > > > + }\n> > > > > > > > +\n> > > > > > > > +private:\n> > > > > > > > + void gstreamer_print_error(GstMessage *msg)\n> > > > > > > > + {\n> > > > > > > > +         GError *err;\n> > > > > > > > +         gchar *debug_info;\n> > > > > > > > +\n> > > > > > > > +         gst_message_parse_error(msg, &err, &debug_info);\n> > > > > > > > +         g_printerr(\"Error received from element %s: %s\\n\",\n> > > > > > > > +                    GST_OBJECT_NAME(msg->src), err->message);\n> > > > > > > > +         g_printerr(\"Debugging information: %s\\n\",\n> > > > > > > > +                    debug_info ? debug_info : \"none\");\n> > > > > > > > +         g_clear_error(&err);\n> > > > > > > > +         g_free(debug_info);\n> > > > > > > > + }\n> > > > > > > > +\n> > > > > > > > + GstElement *pipeline_;\n> > > > > > > > + GstElement *libcameraSrc_;\n> > > > > > > > + GstElement *convert0_;\n> > > > > > > > + GstElement *sink0_;\n> > > > > > > > +};\n> > > > > > > > +\n> > > > > > > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > > > > > > diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build\n> > > > > > > > new file mode 100644\n> > > > > > > > index 00000000..b99aa0da\n> > > > > > > > --- /dev/null\n> > > > > > > > +++ b/test/gstreamer/meson.build\n> > > > > > > > @@ -0,0 +1,19 @@\n> > > > > > > > +# SPDX-License-Identifier: CC0-1.0\n> > > > > > > > +\n> > > > > > > > +if not gst_enabled\n> > > > > > > > +    subdir_done()\n> > > > > > > > +endif\n> > > > > > > > +\n> > > > > > > > +gstreamer_tests = [\n> > > > > > > > +    ['single_stream_test',  'gstreamer_single_stream_test.cpp'],\n> > > > > > > > +]\n> > > > > > > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > > > > > > +\n> > > > > > > > +foreach t : gstreamer_tests\n> > > > > > > > +    exe = executable(t[0], t[1],\n> > > > > > > > +                     dependencies : [libcamera_private, gstreamer_dep],\n> > > > > > > > +                     link_with : test_libraries,\n> > > > > > > > +                     include_directories : test_includes_internal)\n> > > > > > > > +\n> > > > > > > > +    test(t[0], exe, suite : 'gstreamer', is_parallel : false)\n> > > > > > > > +endforeach\n> > > > > > > > diff --git a/test/meson.build b/test/meson.build\n> > > > > > > > index 3bceb5df..d0466f17 100644\n> > > > > > > > --- a/test/meson.build\n> > > > > > > > +++ b/test/meson.build\n> > > > > > > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > > > > > > >\n> > > > > > > >  subdir('camera')\n> > > > > > > >  subdir('controls')\n> > > > > > > > +subdir('gstreamer')\n> > > > > > > >  subdir('ipa')\n> > > > > > > >  subdir('ipc')\n> > > > > > > >  subdir('log')","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 35AB9C3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 18:42:44 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 946BF68891;\n\tFri, 13 Aug 2021 20:42:43 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6FAC8687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 20:42:42 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E4415DD;\n\tFri, 13 Aug 2021 20:42:41 +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=\"GsHr7iNh\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628880162;\n\tbh=iyjofd/1+X/0GXekvEMbDoDT2nhVt7qfSPwac1iA/Vo=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=GsHr7iNhmJwWF185iW4WO+3ewjj+rJKU1j0sXvOU6S/C94VzYSVFBJkpfUw3x1wNo\n\t2VHyZ003Ub0TXGQrTC2Nj2tLD6dQxdekY7Q9cidTLivHS5dDbQMaTyN/kRy9wMsymu\n\tus2pzlm33ZqkuxcQN77xcpkhzpIJ8vCbPYuxL04M=","Date":"Fri, 13 Aug 2021 21:42:37 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Message-ID":"<YRa9HRYmIHvn+dMn@pendragon.ideasonboard.com>","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>\n\t<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>\n\t<CACGrz-M77Fk=hZYFKztXmZgVJE52OEnaBJRwP_UZmdb=vhnpLg@mail.gmail.com>\n\t<YRakwqBu6+7e/23X@pendragon.ideasonboard.com>\n\t<CACGrz-MGFx7Ju9tkpH+pmdWwNUc8aFtKrC-VuXKirXhFjWnn2A@mail.gmail.com>\n\t<YRa8ZzMTI/t1s8lD@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<YRa8ZzMTI/t1s8lD@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18786,"web_url":"https://patchwork.libcamera.org/comment/18786/","msgid":"<CACGrz-OLKzFyV1aMyYHW7Bk8aCM0sTdgdtsnEVbzLULa1fHYDw@mail.gmail.com>","date":"2021-08-13T18:42:58","subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single stream","submitter":{"id":85,"url":"https://patchwork.libcamera.org/api/people/85/","name":"Vedant Paranjape","email":"vedantparanjape160201@gmail.com"},"content":"Hi Laurent,\n\n\nOn Sat, Aug 14, 2021 at 12:09 AM Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> Hi Vedant,\n>\n> On Fri, Aug 13, 2021 at 10:31:43PM +0530, Vedant Paranjape wrote:\n> > Hi Laurent,\n> >\n> > vedant@veware ~/Programming/contributing/libcamera$\n> > ./build/test/gstreamer/single_stream_test\n> >                                            ✹ ✭wip-negotiation\n> > [11:45:45.304648653] [243629]  INFO IPAManager ipa_manager.cpp:138\n> libcamera is not installed. Adding\n> '/home/vedant/Programming/contributing/libcamera/build/src/ipa' to the IPA\n> search path\n> > [11:45:45.306046376] [243629]  INFO Camera camera_manager.cpp:294\n> libcamera v0.0.0+2877-e3edb100-dirty (2021-08-13T22:11:47+05:30)\n> > [11:45:45.319737506] [243632]  INFO Camera camera.cpp:870 configuring\n> streams: (0) 640x360-YUYV\n>\n> As discussed on IRC, that didn't have asan enabled.\n>\n> Running\n>\n> LD_DEBUG=libs ./test/gstreamer/single_stream_test\n>\n> gives useful information. GStreamer spawns a new process,\n> gst-plugin-scanner, to locate the libcamerasrc plugin. As gstreamer is\n> compiled without asan, the gst-plugin-scanner process has lots of\n> libraries loaded when it dlopen()s the plugin .so, which results in a\n> failure in the asan library order sanity check, producing the messages\n>\n> ==24099==ASan runtime does not come first in initial library list; you\n> should either link runtime to your application or manually preload it with\n> LD_PRELOAD.\n> ==24100==ASan runtime does not come first in initial library list; you\n> should either link runtime to your application or manually preload it with\n> LD_PRELOAD.\n>\n> I'm getting the exact same two messages when running gst-inspect or\n> gst-launch. However,\n>\n> gst-launch-1.0 --gst-plugin-path=$(pwd)/src/gstreamer/ libcamerasrc !\n> videoconvert ! fakesink\n>\n> doesn't fail. There may thus be something we're doing wrong, or at least\n> in a different way.\n>\n\nI think somehow in this case libasan is loaded first then gstreamer looks\nfor plugins.\n\n> On Fri, Aug 13, 2021 at 10:28 PM Laurent Pinchart wrote:\n> > > On Fri, Aug 13, 2021 at 10:14:09PM +0530, Vedant Paranjape wrote:\n> > > > Hi Laurent,\n> > > > I was unable to reproduce the issue with address sanitizer.\n> > > >\n> > > > Steps I followed:\n> > > > 1) meson --reconfigure build -Db_sanitize=address\n> > > > 2) ninja -C build test\n> > >\n> > > What's the full output of the gstreamer test when you run it manually ?\n> > >\n> > > > On Fri, Aug 13, 2021 at 8:07 PM Laurent Pinchart wrote:\n> > > > > On Fri, Aug 13, 2021 at 05:04:01PM +0300, Laurent Pinchart wrote:\n> > > > > > On Fri, Aug 13, 2021 at 03:57:22PM +0300, Laurent Pinchart wrote:\n> > > > > > > Hi Vedant,\n> > > > > > >\n> > > > > > > Thank you for the patch.\n> > > > > > >\n> > > > > > > On Fri, Aug 13, 2021 at 04:13:02PM +0530, Vedant Paranjape\n> wrote:\n> > > > > > > > This patch adds a test to test if single stream using\n> > > > > > > > libcamera's gstreamer element works.\n> > > > > > > >\n> > > > > > > > Signed-off-by: Vedant Paranjape <\n> vedantparanjape160201@gmail.com\n> > > > > > > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> > > > > > > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com\n> >\n> > > > > > > > ---\n> > > > > > > >  .../gstreamer_single_stream_test.cpp          | 153\n> ++++++++++++++++++\n> > > > > > > >  test/gstreamer/meson.build                    |  19 +++\n> > > > > > > >  test/meson.build                              |   1 +\n> > > > > > > >  3 files changed, 173 insertions(+)\n> > > > > > > >  create mode 100644\n> test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > > >  create mode 100644 test/gstreamer/meson.build\n> > > > > > > >\n> > > > > > > > diff --git a/test/gstreamer/gstreamer_single_stream_test.cpp\n> b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > > > new file mode 100644\n> > > > > > > > index 00000000..eecd3274\n> > > > > > > > --- /dev/null\n> > > > > > > > +++ b/test/gstreamer/gstreamer_single_stream_test.cpp\n> > > > > > > > @@ -0,0 +1,153 @@\n> > > > > > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > > > > > > > +/*\n> > > > > > > > + * Copyright (C) 2021, Vedant Paranjape\n> > > > > > > > + *\n> > > > > > > > + * ipa_interface_test.cpp - Test the IPA interface\n> > > > > > > > + */\n> > > > > > > > +\n> > > > > > > > +#include <iostream>\n> > > > > > > > +\n> > > > > > > > +#include <libcamera/base/utils.h>\n> > > > > > > > +\n> > > > > > > > +#include <gst/gst.h>\n> > > > > > > > +\n> > > > > > > > +#include \"test.h\"\n> > > > > > > > +\n> > > > > > > > +using namespace std;\n> > > > > > > > +\n> > > > > > > > +class GstreamerSingleStreamTest : public Test\n> > > > > > > > +{\n> > > > > > > > +protected:\n> > > > > > > > + int init() override\n> > > > > > > > + {\n> > > > > > > > +         /* Initialize GStreamer */\n> > > > > > > > +         GError *errInit = nullptr;\n> > > > > > > > +         if (!gst_init_check(nullptr, nullptr, &errInit)) {\n> > > > > > > > +                 g_printerr(\"Could not initialize\n> GStreamer: %s\\n\",\n> > > > > > > > +                            errInit ? errInit->message :\n> \"unknown error\");\n> > > > > > > > +                 if (errInit)\n> > > > > > > > +                         g_error_free(errInit);\n> > > > > > > > +\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         /*\n> > > > > > > > +         * Remove the system libcamera plugin, if any, and\n> add the\n> > > > > > > > +         * plugin from the build directory.\n> > > > > > > > +         */\n> > > > > > >\n> > > > > > > Missing space before *\n> > > > > > >\n> > > > > > > > +         GstRegistry *registry = gst_registry_get();\n> > > > > > > > +         GstPlugin *plugin = gst_registry_lookup(registry,\n> \"libgstlibcamera.so\");\n> > > > > > > > +         if (plugin) {\n> > > > > > > > +                 gst_registry_remove_plugin(registry,\n> plugin);\n> > > > > > > > +                 gst_object_unref(plugin);\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > >\n> > > > > > > Extra blank spaces at the end of the line.\n> > > > > > >\n> > > > > > > > +         std::string path =\n> std::string(libcamera::utils::libcameraBuildPath()\n> > > > > > > > +                                 + \"src/gstreamer\");\n> > > > > > >\n> > > > > > > No need for calling the std::string constructor explictly,\n> > > > > > > libcamera::utils::libcameraBuildPath() returns an std::string\n> and the\n> > > > > > > result of the operator+() call is also an std::string.\n> > > > > > >\n> > > > > > > You should #include \"libcamera/internal/source_paths.h\"\" for\n> > > > > > > libcamera::utils::libcameraBuildPath().\n> > > > > > >\n> > > > > > > I'll fix these small issues when applying.\n> > > > > > >\n> > > > > > > > +         if (!gst_registry_scan_path(registry,\n> path.c_str())) {\n> > > > > > > > +                 g_printerr(\"Failed to add plugin to\n> registry\\n\");\n> > > > > > > > +                 gst_deinit();\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         /* Create the elements */\n> > > > > > > > +         libcameraSrc_ =\n> gst_element_factory_make(\"libcamerasrc\", \"libcamera\");\n> > > > >\n> > > > > And now I'm getting a failure here :-( When compiling with gcc,\n> and with\n> > > > > the meson b_sanitize option set to 'address', this call returns\n> null.\n> > > > >\n> > > > > 10/64 libcamera:gstreamer / single_stream_test\n> > > > >  FAIL            0.48s   exit status 1\n> > > > > >>> MALLOC_PERTURB_=101\n> > > > > build/x86-gcc-11.1.0/test/gstreamer/single_stream_test\n> > > > >\n> ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> ✀\n> ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > > > > stderr:\n> > > > > ==14992==ASan runtime does not come first in initial library list;\n> you should either link runtime to your application or manually preload it\n> with LD_PRELOAD.\n> > > > > ==14993==ASan runtime does not come first in initial library list;\n> you should either link runtime to your application or manually preload it\n> with LD_PRELOAD.\n> > > > > Not all elements could be created.\n> 0x6290000241f0.0x61a000019950.0x61a00001a670.(nil)\n> > > > >\n> > > > > =================================================================\n> > > > > ==14990==ERROR: LeakSanitizer: detected memory leaks\n> > > > >\n> > > > > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> > > > >     #0 0x7f9daade1ac7 in __interceptor_malloc\n> > > > >\n> /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> > > > >     #1 0x7f9da776a938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> > > > >\n> > > > > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> > > > >\n> > > > >\n> ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n> > > > >\n> > > > > 11/64 libcamera:ipa / ipa_module_test\n> > > > > OK              0.08s\n> > > > >\n> > > > > Interestingly, if I run the test with\n> > > > >\n> > > > > LD_PRELOAD=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/libasan.so.6\n> > > > > ./test/gstreamer/single_stream_test\n> > > > >\n> > > > > then is runs fine:\n> > > > >\n> > > > > [25:59:46.412146534] [18711]  INFO IPAManager ipa_manager.cpp:138\n> libcamera is not installed. Adding '[...]/build/x86-gcc-11.1.0/src/ipa' to\n> the IPA search path\n> > > > > [25:59:46.413634330] [18711]  INFO Camera camera_manager.cpp:294\n> libcamera v0.0.0+2881-24c1e91b-dirty (2021-08-13T17:24:37+03:00)\n> > > > > [25:59:46.663097368] [18714]  WARN CameraSensorProperties\n> camera_sensor_properties.cpp:123 No static properties available for 'Sensor\n> B'\n> > > > > [25:59:46.663129122] [18714]  WARN CameraSensorProperties\n> camera_sensor_properties.cpp:125 Please consider updating the camera sensor\n> properties database\n> > > > > [25:59:46.663156409] [18714]  WARN CameraSensor\n> camera_sensor.cpp:403 'Sensor B': Failed to retrieve the camera location\n> > > > > [25:59:46.664891182] [18714]  INFO IPAProxy ipa_proxy.cpp:130\n> libcamera is not installed. Loading IPA configuration from\n> '[...]/src/ipa/vimc/data'\n> > > > > [25:59:46.680563655] [18715]  INFO Camera camera.cpp:870\n> configuring streams: (0) 160x120-YUYV\n> > > > >\n> > > > > =================================================================\n> > > > > ==18711==ERROR: LeakSanitizer: detected memory leaks\n> > > > >\n> > > > > Direct leak of 16384 byte(s) in 1 object(s) allocated from:\n> > > > >     #0 0x7effa6393ac7 in __interceptor_malloc\n> > > > >\n> /var/tmp/portage/sys-devel/gcc-11.1.0-r2/work/gcc-11.1.0/libsanitizer/asan/asan_malloc_linux.cpp:145\n> > > > >     #1 0x7effa57be938 in g_malloc ../glib-2.68.3/glib/gmem.c:106\n> > > > >\n> > > > > SUMMARY: AddressSanitizer: 16384 byte(s) leaked in 1 allocation(s).\n> > > > >\n> > > > > The leak is a known glib issue, caught by valgrind too, so I'm not\n> > > > > worried about it. The test failing to run is however a blocker.\n> > > > >\n> > > > > Vedant, can you reproduce the failure with the address sanitizer ?\n> > > > >\n> > > > > > > > +         convert0_ =\n> gst_element_factory_make(\"videoconvert\", \"convert0\");\n> > > > > > > > +         sink0_ = gst_element_factory_make(\"fakesink\",\n> \"sink0\");\n> > > > > > > > +\n> > > > > > > > +         /* Create the empty pipeline_ */\n> > > > > > > > +         pipeline_ = gst_pipeline_new(\"test-pipeline\");\n> > > > > > > > +\n> > > > > > > > +         if (!pipeline_ || !convert0_ || !sink0_ ||\n> !libcameraSrc_) {\n> > > > > > > > +                 g_printerr(\"Not all elements could be\n> created. %p.%p.%p.%p\\n\",\n> > > > > > > > +                            pipeline_, convert0_, sink0_,\n> libcameraSrc_);\n> > > > > > > > +                 if (pipeline_)\n> > > > > > > > +                         gst_object_unref(pipeline_);\n> > > > > > > > +                 if (convert0_)\n> > > > > > > > +                         gst_object_unref(convert0_);\n> > > > > > > > +                 if (sink0_)\n> > > > > > > > +                         gst_object_unref(sink0_);\n> > > > > > > > +                 if (libcameraSrc_)\n> > > > > > > > +                         gst_object_unref(libcameraSrc_);\n> > > > > > > > +                 gst_deinit();\n> > > > > > > > +\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         return TestPass;\n> > > > > > > > + }\n> > > > > > > > +\n> > > > > > > > + void cleanup() override\n> > > > > > > > + {\n> > > > > > > > +         gst_object_unref(pipeline_);\n> > > > > > > > +         gst_deinit();\n> > > > > > > > + }\n> > > > > > > > +\n> > > > > > > > + int run() override\n> > > > > > > > + {\n> > > > > > > > +         GstStateChangeReturn ret;\n> > > > > > > > +         g_autoptr(GstBus) bus;\n> > > > > > > > +         g_autoptr(GstMessage) msg;\n> > > > > >\n> > > > > > I've also had to initialize those two variables to nullptr, to\n> fix\n> > > > > >\n> > > > > > In file included from /usr/lib/glib-2.0/include/glibconfig.h:9,\n> > > > > >                  from /usr/include/glib-2.0/glib/gtypes.h:32,\n> > > > > >                  from /usr/include/glib-2.0/glib/galloca.h:32,\n> > > > > >                  from /usr/include/glib-2.0/glib.h:30,\n> > > > > >                  from /usr/include/gstreamer-1.0/gst/gst.h:27,\n> > > > > >                  from\n> > > > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:14:\n> > > > > > /usr/include/glib-2.0/glib/gmacros.h: In member function\n> ‘virtual int GstreamerSingleStreamTest::run()’:\n> > > > > > /usr/include/glib-2.0/glib/gmacros.h:1045:7: error: ‘msg’ may be\n> used uninitialized in this function [-Werror=maybe-uninitialized]\n> > > > > >  1045 |     { if (_ptr) (cleanup) ((ParentName *) _ptr); }\n> > > > >                                                 \\\n> > > > > >       |       ^~\n> > > > > > ../../test/gstreamer/gstreamer_single_stream_test.cpp:108:25:\n> note: ‘msg’ was declared here\n> > > > > >   108 |   g_autoptr(GstMessage) msg;\n> > > > > >       |                         ^~~\n> > > > > >\n> > > > > > when cross-compiling for ARM.\n> > > > > >\n> > > > > > > > +\n> > > > > > > > +         /* Build the pipeline */\n> > > > > > > > +         gst_bin_add_many(GST_BIN(pipeline_),\n> libcameraSrc_, convert0_, sink0_, NULL);\n> > > > > > > > +         if (gst_element_link_many(libcameraSrc_,\n> convert0_, sink0_, NULL) != TRUE) {\n> > > > > > > > +                 g_printerr(\"Elements could not be\n> linked.\\n\");\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         /* Start playing */\n> > > > > > > > +         ret = gst_element_set_state(pipeline_,\n> GST_STATE_PLAYING);\n> > > > > > > > +         if (ret == GST_STATE_CHANGE_FAILURE) {\n> > > > > > > > +                 g_printerr(\"Unable to set the pipeline to\n> the playing state.\\n\");\n> > > > > > > > +                 return TestFail;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         /* Wait until error or EOS or timeout after 2\n> seconds */\n> > > > > > > > +         GstClockTime timeout = 2000000000;\n> > > > > > > > +         bus = gst_element_get_bus(pipeline_);\n> > > > > > > > +         msg = gst_bus_timed_pop_filtered(bus, timeout,\n> > > > > > > > +\n> GstMessageType((uint)GST_MESSAGE_ERROR | (uint)GST_MESSAGE_EOS));\n> > > > > > > > +         gst_element_set_state(pipeline_, GST_STATE_NULL);\n> > > > > > > > +\n> > > > > > > > +         /* Parse error message */\n> > > > > > > > +         if (msg == NULL)\n> > > > > > > > +                 return TestPass;\n> > > > > > > > +\n> > > > > > > > +         switch (GST_MESSAGE_TYPE(msg)) {\n> > > > > > > > +         case GST_MESSAGE_ERROR:\n> > > > > > > > +                 gstreamer_print_error(msg);\n> > > > > > > > +                 break;\n> > > > > > > > +         case GST_MESSAGE_EOS:\n> > > > > > > > +                 g_print(\"End-Of-Stream reached.\\n\");\n> > > > > > > > +                 break;\n> > > > > > > > +         default:\n> > > > > > > > +                 g_printerr(\"Unexpected message\n> received.\\n\");\n> > > > > > > > +                 break;\n> > > > > > > > +         }\n> > > > > > > > +\n> > > > > > > > +         return TestFail;\n> > > > > > > > + }\n> > > > > > > > +\n> > > > > > > > +private:\n> > > > > > > > + void gstreamer_print_error(GstMessage *msg)\n> > > > > > > > + {\n> > > > > > > > +         GError *err;\n> > > > > > > > +         gchar *debug_info;\n> > > > > > > > +\n> > > > > > > > +         gst_message_parse_error(msg, &err, &debug_info);\n> > > > > > > > +         g_printerr(\"Error received from element %s: %s\\n\",\n> > > > > > > > +                    GST_OBJECT_NAME(msg->src),\n> err->message);\n> > > > > > > > +         g_printerr(\"Debugging information: %s\\n\",\n> > > > > > > > +                    debug_info ? debug_info : \"none\");\n> > > > > > > > +         g_clear_error(&err);\n> > > > > > > > +         g_free(debug_info);\n> > > > > > > > + }\n> > > > > > > > +\n> > > > > > > > + GstElement *pipeline_;\n> > > > > > > > + GstElement *libcameraSrc_;\n> > > > > > > > + GstElement *convert0_;\n> > > > > > > > + GstElement *sink0_;\n> > > > > > > > +};\n> > > > > > > > +\n> > > > > > > > +TEST_REGISTER(GstreamerSingleStreamTest)\n> > > > > > > > diff --git a/test/gstreamer/meson.build\n> b/test/gstreamer/meson.build\n> > > > > > > > new file mode 100644\n> > > > > > > > index 00000000..b99aa0da\n> > > > > > > > --- /dev/null\n> > > > > > > > +++ b/test/gstreamer/meson.build\n> > > > > > > > @@ -0,0 +1,19 @@\n> > > > > > > > +# SPDX-License-Identifier: CC0-1.0\n> > > > > > > > +\n> > > > > > > > +if not gst_enabled\n> > > > > > > > +    subdir_done()\n> > > > > > > > +endif\n> > > > > > > > +\n> > > > > > > > +gstreamer_tests = [\n> > > > > > > > +    ['single_stream_test',\n> 'gstreamer_single_stream_test.cpp'],\n> > > > > > > > +]\n> > > > > > > > +gstreamer_dep = dependency('gstreamer-1.0', required: true)\n> > > > > > > > +\n> > > > > > > > +foreach t : gstreamer_tests\n> > > > > > > > +    exe = executable(t[0], t[1],\n> > > > > > > > +                     dependencies : [libcamera_private,\n> gstreamer_dep],\n> > > > > > > > +                     link_with : test_libraries,\n> > > > > > > > +                     include_directories :\n> test_includes_internal)\n> > > > > > > > +\n> > > > > > > > +    test(t[0], exe, suite : 'gstreamer', is_parallel :\n> false)\n> > > > > > > > +endforeach\n> > > > > > > > diff --git a/test/meson.build b/test/meson.build\n> > > > > > > > index 3bceb5df..d0466f17 100644\n> > > > > > > > --- a/test/meson.build\n> > > > > > > > +++ b/test/meson.build\n> > > > > > > > @@ -11,6 +11,7 @@ subdir('libtest')\n> > > > > > > >\n> > > > > > > >  subdir('camera')\n> > > > > > > >  subdir('controls')\n> > > > > > > > +subdir('gstreamer')\n> > > > > > > >  subdir('ipa')\n> > > > > > > >  subdir('ipc')\n> > > > > > > >  subdir('log')\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\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 BEF53C3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Aug 2021 18:43:12 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7705668891;\n\tFri, 13 Aug 2021 20:43:12 +0200 (CEST)","from mail-yb1-xb29.google.com (mail-yb1-xb29.google.com\n\t[IPv6:2607:f8b0:4864:20::b29])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7BDBC687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 20:43:11 +0200 (CEST)","by mail-yb1-xb29.google.com with SMTP id m193so20502955ybf.9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Aug 2021 11:43:11 -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=\"uWVi2hsQ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=nZz7MRIqRbtCc0Ju38ZmPCIRoZKnxSE2mzh+zFs4e7E=;\n\tb=uWVi2hsQF4joYNTAbX281XHhWltFfgcOkGHZEIMl9KkmviffGwJtcy6XBYHuYDxr1H\n\tIhmI2Vqsg1wChz4VTOmZfwMh0354/4uUd0hNPprl1Nyx8yrsK7udbq64L7LIRo8+uae+\n\tgTaSfxRGk/8tx6vtz3MRkefcVDM+F2pnSvFUjbcL9dIjZeHwScqP6VgWEkD6Ymi8qgwL\n\tfnOg45s0yRMO52+cTQjm/bdjuBVF0mKL9GJ/zFPfLO7J56VoOmiCrqyHzuPS1NzZBEUK\n\tqiAXgspr0t5wAeVjvGmRW8sNUUtbQJsvN03qugjI9UlnJ6zpVRyWrDnxrfVeB6FzgpWU\n\tuHQw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=nZz7MRIqRbtCc0Ju38ZmPCIRoZKnxSE2mzh+zFs4e7E=;\n\tb=FC5/mSq/h0C7zoQDOQTypP3gDTiC3ste+hHybfsThjI0vb8iIFksJh3mWKnr0kDfmm\n\t6QOl19pbPWctkQAr9RMBXiJo1+1mUASf1xE1QlmxVjTwOowR863XAHouw47h8JQtqgU7\n\tNtVUegTzBqO4ZBOGQxehMWEB+nS5RRIiwb3z0cGq+Fwyu+YfMFNRw7W1w8XV5TISuycZ\n\tHN15mjs3ii8UfpVYK1HVc1eYKXUshiQlIlLhW1u+htDgKJqSrpVeGCU2vWjKo2LMZ4cJ\n\tJmf9vAGU8oZloBkOSs627ClPNk9oIKvrMQqasWfnzxKSA/D9uV1zxDUeSMLo3kgZetmt\n\tU9bA==","X-Gm-Message-State":"AOAM530rHFqYeqajNW1TE9La/KyuZ0LhtGCp99yOA7a0yJQ1rZ1AHkUM\n\tU5bd7Vmvr3dL/2l8GaococXwPWRJlxvKreG+zKkkZJo9cLM=","X-Google-Smtp-Source":"ABdhPJwMirX22uWkg3gx6Yz8QPtNdR4xBAdToVqAnAeKUnuGA9kfAyqgFXwXlBGIU/57ycTIQHwGBxbjLuMSwj7/ZP8=","X-Received":"by 2002:a25:37cf:: with SMTP id\n\te198mr4561322yba.223.1628880190225; \n\tFri, 13 Aug 2021 11:43:10 -0700 (PDT)","MIME-Version":"1.0","References":"<20210813104302.200994-1-vedantparanjape160201@gmail.com>\n\t<YRZsMfvo3cGzxBv9@pendragon.ideasonboard.com>\n\t<YRZ70UPexbyNzdTC@pendragon.ideasonboard.com>\n\t<YRaDnNo8xwoXQSuO@pendragon.ideasonboard.com>\n\t<CACGrz-M77Fk=hZYFKztXmZgVJE52OEnaBJRwP_UZmdb=vhnpLg@mail.gmail.com>\n\t<YRakwqBu6+7e/23X@pendragon.ideasonboard.com>\n\t<CACGrz-MGFx7Ju9tkpH+pmdWwNUc8aFtKrC-VuXKirXhFjWnn2A@mail.gmail.com>\n\t<YRa8ZzMTI/t1s8lD@pendragon.ideasonboard.com>","In-Reply-To":"<YRa8ZzMTI/t1s8lD@pendragon.ideasonboard.com>","From":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Date":"Sat, 14 Aug 2021 00:12:58 +0530","Message-ID":"<CACGrz-OLKzFyV1aMyYHW7Bk8aCM0sTdgdtsnEVbzLULa1fHYDw@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"0000000000001ebfa805c9753947\"","Subject":"Re: [libcamera-devel] [PATCH v10] test: gstreamer: Add test for\n\tgstreamer single 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@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]