[{"id":2395,"web_url":"https://patchwork.libcamera.org/comment/2395/","msgid":"<20190813102028.2gmh4zkw3ioxiivl@uno.localdomain>","date":"2019-08-13T10:20:28","subject":"Re: [libcamera-devel] [PATCH v3 4/6] test: v4l2_videodevice: Add\n\tM2M device test","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Kieran,\n\nOn Tue, Aug 13, 2019 at 10:40:18AM +0100, Kieran Bingham wrote:\n> The V4L2M2MDevice requires two video devices to be configured. This\n> makes it unsuitable to reuse the existing V4L2DeviceTest test library in\n> its current form.\n>\n> Implement a full test to run the two M2M pipelines through VIM2M.\n>\n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nLooks good to me\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n  j\n\n> ---\n>  test/v4l2_videodevice/meson.build        |   1 +\n>  test/v4l2_videodevice/v4l2_m2mdevice.cpp | 212 +++++++++++++++++++++++\n>  2 files changed, 213 insertions(+)\n>  create mode 100644 test/v4l2_videodevice/v4l2_m2mdevice.cpp\n>\n> diff --git a/test/v4l2_videodevice/meson.build b/test/v4l2_videodevice/meson.build\n> index 76be5e142bb6..ad41898b5f8b 100644\n> --- a/test/v4l2_videodevice/meson.build\n> +++ b/test/v4l2_videodevice/meson.build\n> @@ -7,6 +7,7 @@ v4l2_videodevice_tests = [\n>      [ 'stream_on_off',      'stream_on_off.cpp' ],\n>      [ 'capture_async',      'capture_async.cpp' ],\n>      [ 'buffer_sharing',     'buffer_sharing.cpp' ],\n> +    [ 'v4l2_m2mdevice',     'v4l2_m2mdevice.cpp' ],\n>  ]\n>\n>  foreach t : v4l2_videodevice_tests\n> diff --git a/test/v4l2_videodevice/v4l2_m2mdevice.cpp b/test/v4l2_videodevice/v4l2_m2mdevice.cpp\n> new file mode 100644\n> index 000000000000..d132b1db2432\n> --- /dev/null\n> +++ b/test/v4l2_videodevice/v4l2_m2mdevice.cpp\n> @@ -0,0 +1,212 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2019, Google Inc.\n> + *\n> + * libcamera V4L2 M2M video device tests\n> + */\n> +\n> +#include <iostream>\n> +\n> +#include <libcamera/buffer.h>\n> +#include <libcamera/camera_manager.h>\n> +#include <libcamera/event_dispatcher.h>\n> +#include <libcamera/timer.h>\n> +\n> +#include \"device_enumerator.h\"\n> +#include \"media_device.h\"\n> +#include \"v4l2_videodevice.h\"\n> +\n> +#include \"test.h\"\n> +\n> +using namespace std;\n> +using namespace libcamera;\n> +\n> +class V4L2M2MDeviceTest : public Test\n> +{\n> +public:\n> +\tV4L2M2MDeviceTest()\n> +\t\t: vim2m_(nullptr), outputFrames_(0), captureFrames_(0)\n> +\t{\n> +\t}\n> +\n> +\tvoid outputBufferComplete(Buffer *buffer)\n> +\t{\n> +\t\tcout << \"Received output buffer \" << buffer->index() << endl;\n> +\n> +\t\toutputFrames_++;\n> +\n> +\t\t/* Requeue the buffer for further use. */\n> +\t\tvim2m_->output()->queueBuffer(buffer);\n> +\t}\n> +\n> +\tvoid receiveCaptureBuffer(Buffer *buffer)\n> +\t{\n> +\t\tcout << \"Received capture buffer \" << buffer->index() << endl;\n> +\n> +\t\tcaptureFrames_++;\n> +\n> +\t\t/* Requeue the buffer for further use. */\n> +\t\tvim2m_->capture()->queueBuffer(buffer);\n> +\t}\n> +\n> +protected:\n> +\tint init()\n> +\t{\n> +\t\tenumerator_ = DeviceEnumerator::create();\n> +\t\tif (!enumerator_) {\n> +\t\t\tcerr << \"Failed to create device enumerator\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (enumerator_->enumerate()) {\n> +\t\t\tcerr << \"Failed to enumerate media devices\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tDeviceMatch dm(\"vim2m\");\n> +\t\tdm.add(\"vim2m-source\");\n> +\t\tdm.add(\"vim2m-sink\");\n> +\n> +\t\tmedia_ = enumerator_->search(dm);\n> +\t\tif (!media_) {\n> +\t\t\tcerr << \"No vim2m device found\" << endl;\n> +\t\t\treturn TestSkip;\n> +\t\t}\n> +\n> +\t\treturn TestPass;\n> +\t}\n> +\n> +\tint run()\n> +\t{\n> +\t\tconstexpr unsigned int bufferCount = 4;\n> +\n> +\t\tEventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher();\n> +\t\tint ret;\n> +\n> +\t\tMediaEntity *entity = media_->getEntityByName(\"vim2m-source\");\n> +\t\tvim2m_ = new V4L2M2MDevice(entity->deviceNode());\n> +\t\tif (vim2m_->open()) {\n> +\t\t\tcerr << \"Failed to open VIM2M device\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tV4L2VideoDevice *capture = vim2m_->capture();\n> +\t\tV4L2VideoDevice *output = vim2m_->output();\n> +\n> +\t\tV4L2DeviceFormat format = {};\n> +\t\tif (capture->getFormat(&format)) {\n> +\t\t\tcerr << \"Failed to get capture format\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tformat.size.width = 640;\n> +\t\tformat.size.height = 480;\n> +\n> +\t\tif (capture->setFormat(&format)) {\n> +\t\t\tcerr << \"Failed to set capture format\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (output->setFormat(&format)) {\n> +\t\t\tcerr << \"Failed to set output format\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tcapturePool_.createBuffers(bufferCount);\n> +\t\toutputPool_.createBuffers(bufferCount);\n> +\n> +\t\tret = capture->exportBuffers(&capturePool_);\n> +\t\tif (ret) {\n> +\t\t\tcerr << \"Failed to export Capture Buffers\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tret = output->exportBuffers(&outputPool_);\n> +\t\tif (ret) {\n> +\t\t\tcerr << \"Failed to export Output Buffers\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tcapture->bufferReady.connect(this, &V4L2M2MDeviceTest::receiveCaptureBuffer);\n> +\t\toutput->bufferReady.connect(this, &V4L2M2MDeviceTest::outputBufferComplete);\n> +\n> +\t\tstd::vector<std::unique_ptr<Buffer>> captureBuffers;\n> +\t\tcaptureBuffers = capture->queueAllBuffers();\n> +\t\tif (captureBuffers.empty()) {\n> +\t\t\tcerr << \"Failed to queue all Capture Buffers\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\t/* We can't \"queueAllBuffers()\" on an output device, so we do it manually */\n> +\t\tstd::vector<std::unique_ptr<Buffer>> outputBuffers;\n> +\t\tfor (unsigned int i = 0; i < outputPool_.count(); ++i) {\n> +\t\t\tBuffer *buffer = new Buffer(i);\n> +\t\t\toutputBuffers.emplace_back(buffer);\n> +\t\t\tret = output->queueBuffer(buffer);\n> +\t\t\tif (ret) {\n> +\t\t\t\tcerr << \"Failed to queue output buffer\" << i << endl;\n> +\t\t\t\treturn TestFail;\n> +\t\t\t}\n> +\t\t}\n> +\n> +\t\tret = capture->streamOn();\n> +\t\tif (ret) {\n> +\t\t\tcerr << \"Failed to streamOn capture\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tret = output->streamOn();\n> +\t\tif (ret) {\n> +\t\t\tcerr << \"Failed to streamOn output\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tTimer timeout;\n> +\t\ttimeout.start(5000);\n> +\t\twhile (timeout.isRunning()) {\n> +\t\t\tdispatcher->processEvents();\n> +\t\t\tif (captureFrames_ > 30)\n> +\t\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\tcerr << \"Output \" << outputFrames_ << \" frames\" << std::endl;\n> +\t\tcerr << \"Captured \" << captureFrames_ << \" frames\" << std::endl;\n> +\n> +\t\tif (captureFrames_ < 30) {\n> +\t\t\tcerr << \"Failed to capture 30 frames within timeout.\" << std::endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tret = capture->streamOff();\n> +\t\tif (ret) {\n> +\t\t\tcerr << \"Failed to StreamOff the capture device.\" << std::endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tret = output->streamOff();\n> +\t\tif (ret) {\n> +\t\t\tcerr << \"Failed to StreamOff the output device.\" << std::endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\treturn TestPass;\n> +\t}\n> +\n> +\tvoid cleanup()\n> +\t{\n> +\t\tdelete vim2m_;\n> +\t};\n> +\n> +private:\n> +\tstd::unique_ptr<DeviceEnumerator> enumerator_;\n> +\tstd::shared_ptr<MediaDevice> media_;\n> +\tV4L2M2MDevice *vim2m_;\n> +\n> +\tBufferPool capturePool_;\n> +\tBufferPool outputPool_;\n> +\n> +\tunsigned int outputFrames_;\n> +\tunsigned int captureFrames_;\n> +};\n> +\n> +TEST_REGISTER(V4L2M2MDeviceTest);\n> --\n> 2.20.1\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net\n\t[217.70.183.193])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 663FA60C43\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 13 Aug 2019 12:19:02 +0200 (CEST)","from uno.localdomain (2-224-242-101.ip172.fastwebnet.it\n\t[2.224.242.101]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay1-d.mail.gandi.net (Postfix) with ESMTPSA id B71A9240012;\n\tTue, 13 Aug 2019 10:19:01 +0000 (UTC)"],"X-Originating-IP":"2.224.242.101","Date":"Tue, 13 Aug 2019 12:20:28 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","Message-ID":"<20190813102028.2gmh4zkw3ioxiivl@uno.localdomain>","References":"<20190813094020.10277-1-kieran.bingham@ideasonboard.com>\n\t<20190813094020.10277-5-kieran.bingham@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha256;\n\tprotocol=\"application/pgp-signature\"; boundary=\"gp43knaroxlijnoz\"","Content-Disposition":"inline","In-Reply-To":"<20190813094020.10277-5-kieran.bingham@ideasonboard.com>","User-Agent":"NeoMutt/20180716","Subject":"Re: [libcamera-devel] [PATCH v3 4/6] test: v4l2_videodevice: Add\n\tM2M device test","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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>","X-List-Received-Date":"Tue, 13 Aug 2019 10:19:02 -0000"}}]