Message ID | 20220324125444.1389060-1-kieran.bingham@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Kieran, Thank you for the patch. On Thu, Mar 24, 2022 at 12:54:44PM +0000, Kieran Bingham via libcamera-devel wrote: > Add a test that captures 5 frames, with a short (5ms) watchdog. > The default framerate of the VIMC pipeline should ensure that > we never meet this watchdog, and the timeout should activate. > > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > --- > test/v4l2_videodevice/dequeue_watchdog.cpp | 100 +++++++++++++++++++++ > test/v4l2_videodevice/meson.build | 1 + > 2 files changed, 101 insertions(+) > create mode 100644 test/v4l2_videodevice/dequeue_watchdog.cpp > > diff --git a/test/v4l2_videodevice/dequeue_watchdog.cpp b/test/v4l2_videodevice/dequeue_watchdog.cpp > new file mode 100644 > index 000000000000..db0c65ff482e > --- /dev/null > +++ b/test/v4l2_videodevice/dequeue_watchdog.cpp > @@ -0,0 +1,100 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * Copyright (C) 2022, Ideas on Board Oy. > + * > + * libcamera V4L2 dequeue watchdog test > + */ > + > +#include <iostream> > + > +#include <libcamera/base/event_dispatcher.h> > +#include <libcamera/base/thread.h> > +#include <libcamera/base/timer.h> > + > +#include <libcamera/framebuffer.h> > + > +#include "v4l2_videodevice_test.h" > + > +using namespace std::chrono_literals; > +using namespace libcamera; I've recently sent a patch that sorts (some of) the tests to use alphabetical order for the using expressions, could you swap those ? > + > +class DequeueWatchdogTest : public V4L2VideoDeviceTest > +{ > +public: > + DequeueWatchdogTest() > + : V4L2VideoDeviceTest("vimc", "Raw Capture 0"), frames(0), barks(0) {} > + > + void receiveBuffer(FrameBuffer *buffer) > + { > + if (buffer->metadata().status == FrameMetadata::FrameCancelled) > + return; > + > + std::cout << "Buffer received" << std::endl; > + frames++; > + > + /* Requeue the buffer for further use. */ > + capture_->queueBuffer(buffer); > + } > + > + void barkCounter() > + { > + std::cout << "Watchdog is barking" << std::endl; > + barks++; > + } Those two functions can be private. > + > +protected: > + int run() > + { > + const unsigned int bufferCount = 8; constexpr > + > + EventDispatcher *dispatcher = Thread::current()->eventDispatcher(); > + Timer timeout; > + > + int ret = capture_->allocateBuffers(bufferCount, &buffers_); > + if (ret < 0) > + return TestFail; > + > + capture_->dequeueTimeout.connect(this, &DequeueWatchdogTest::barkCounter); > + capture_->setDequeueTimeout(5ms); > + > + capture_->bufferReady.connect(this, &DequeueWatchdogTest::receiveBuffer); > + > + for (const std::unique_ptr<FrameBuffer> &buffer : buffers_) { > + if (capture_->queueBuffer(buffer.get())) { > + std::cout << "Failed to queue buffer" << std::endl; > + return TestFail; > + } > + } > + > + ret = capture_->streamOn(); > + if (ret) > + return TestFail; > + > + timeout.start(5s); > + while (timeout.isRunning()) { > + dispatcher->processEvents(); > + if (frames > 5) > + break; > + } > + > + std::cout << "Processed " << frames << " frames and heard " > + << barks << " barks" << std::endl; > + > + if (barks < 1) { if (!barks) { > + std::cout << "Failed to hear any barks." << std::endl; > + return TestFail; > + } > + > + ret = capture_->streamOff(); > + if (ret) > + return TestFail; You could skip the error check as it's not the point of this test. > + > + return TestPass; > + } > + > +private: > + unsigned int frames; > + unsigned int barks; frames_ and barks_. > +}; > + > +TEST_REGISTER(DequeueWatchdogTest) > diff --git a/test/v4l2_videodevice/meson.build b/test/v4l2_videodevice/meson.build > index 643f82edce5e..7a26f53d106a 100644 > --- a/test/v4l2_videodevice/meson.build > +++ b/test/v4l2_videodevice/meson.build > @@ -6,6 +6,7 @@ v4l2_videodevice_tests = [ > ['double_open', 'double_open.cpp'], > ['controls', 'controls.cpp'], > ['formats', 'formats.cpp'], > + ['dequeue_watchdog', 'dequeue_watchdog.cpp'], I wouldn't mind if you sorted the array, while at it. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > ['request_buffers', 'request_buffers.cpp'], > ['buffer_cache', 'buffer_cache.cpp'], > ['stream_on_off', 'stream_on_off.cpp'],
diff --git a/test/v4l2_videodevice/dequeue_watchdog.cpp b/test/v4l2_videodevice/dequeue_watchdog.cpp new file mode 100644 index 000000000000..db0c65ff482e --- /dev/null +++ b/test/v4l2_videodevice/dequeue_watchdog.cpp @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2022, Ideas on Board Oy. + * + * libcamera V4L2 dequeue watchdog test + */ + +#include <iostream> + +#include <libcamera/base/event_dispatcher.h> +#include <libcamera/base/thread.h> +#include <libcamera/base/timer.h> + +#include <libcamera/framebuffer.h> + +#include "v4l2_videodevice_test.h" + +using namespace std::chrono_literals; +using namespace libcamera; + +class DequeueWatchdogTest : public V4L2VideoDeviceTest +{ +public: + DequeueWatchdogTest() + : V4L2VideoDeviceTest("vimc", "Raw Capture 0"), frames(0), barks(0) {} + + void receiveBuffer(FrameBuffer *buffer) + { + if (buffer->metadata().status == FrameMetadata::FrameCancelled) + return; + + std::cout << "Buffer received" << std::endl; + frames++; + + /* Requeue the buffer for further use. */ + capture_->queueBuffer(buffer); + } + + void barkCounter() + { + std::cout << "Watchdog is barking" << std::endl; + barks++; + } + +protected: + int run() + { + const unsigned int bufferCount = 8; + + EventDispatcher *dispatcher = Thread::current()->eventDispatcher(); + Timer timeout; + + int ret = capture_->allocateBuffers(bufferCount, &buffers_); + if (ret < 0) + return TestFail; + + capture_->dequeueTimeout.connect(this, &DequeueWatchdogTest::barkCounter); + capture_->setDequeueTimeout(5ms); + + capture_->bufferReady.connect(this, &DequeueWatchdogTest::receiveBuffer); + + for (const std::unique_ptr<FrameBuffer> &buffer : buffers_) { + if (capture_->queueBuffer(buffer.get())) { + std::cout << "Failed to queue buffer" << std::endl; + return TestFail; + } + } + + ret = capture_->streamOn(); + if (ret) + return TestFail; + + timeout.start(5s); + while (timeout.isRunning()) { + dispatcher->processEvents(); + if (frames > 5) + break; + } + + std::cout << "Processed " << frames << " frames and heard " + << barks << " barks" << std::endl; + + if (barks < 1) { + std::cout << "Failed to hear any barks." << std::endl; + return TestFail; + } + + ret = capture_->streamOff(); + if (ret) + return TestFail; + + return TestPass; + } + +private: + unsigned int frames; + unsigned int barks; +}; + +TEST_REGISTER(DequeueWatchdogTest) diff --git a/test/v4l2_videodevice/meson.build b/test/v4l2_videodevice/meson.build index 643f82edce5e..7a26f53d106a 100644 --- a/test/v4l2_videodevice/meson.build +++ b/test/v4l2_videodevice/meson.build @@ -6,6 +6,7 @@ v4l2_videodevice_tests = [ ['double_open', 'double_open.cpp'], ['controls', 'controls.cpp'], ['formats', 'formats.cpp'], + ['dequeue_watchdog', 'dequeue_watchdog.cpp'], ['request_buffers', 'request_buffers.cpp'], ['buffer_cache', 'buffer_cache.cpp'], ['stream_on_off', 'stream_on_off.cpp'],
Add a test that captures 5 frames, with a short (5ms) watchdog. The default framerate of the VIMC pipeline should ensure that we never meet this watchdog, and the timeout should activate. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> --- test/v4l2_videodevice/dequeue_watchdog.cpp | 100 +++++++++++++++++++++ test/v4l2_videodevice/meson.build | 1 + 2 files changed, 101 insertions(+) create mode 100644 test/v4l2_videodevice/dequeue_watchdog.cpp