summaryrefslogtreecommitdiff
path: root/test/event-dispatcher.cpp
blob: f71c1c0d9fb0bd080082fd7c9c301d2786135887 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * Event dispatcher test
 */

#include <chrono>
#include <iostream>
#include <signal.h>
#include <sys/time.h>

#include <libcamera/base/event_dispatcher.h>
#include <libcamera/base/thread.h>
#include <libcamera/base/timer.h>

#include "test.h"

using namespace libcamera;
using namespace std;
using namespace std::chrono_literals;

static EventDispatcher *dispatcher;
static bool interrupt;

class EventDispatcherTest : public Test
{
protected:
	static void sigAlarmHandler(int)
	{
		cout << "SIGALARM received" << endl;
		if (interrupt)
			dispatcher->interrupt();
	}

	int init()
	{
		dispatcher = Thread::current()->eventDispatcher();

		struct sigaction sa = {};
		sa.sa_handler = &sigAlarmHandler;
		sigaction(SIGALRM, &sa, nullptr);

		return 0;
	}

	int run()
	{
		Timer timer;

		/* Event processing interruption by signal. */
		std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();

		timer.start(1000ms);

		struct itimerval itimer = {};
		itimer.it_value.tv_usec = 500000;
		interrupt = false;
		setitimer(ITIMER_REAL, &itimer, nullptr);

		dispatcher->processEvents();

		std::chrono::steady_clock::time_point stop = std::chrono::steady_clock::now();
		std::chrono::steady_clock::duration duration = stop - start;
		int msecs = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();

		if (abs(msecs - 1000) > 50) {
			cout << "Event processing restart test failed" << endl;
			return TestFail;
		}

		/* Event processing interruption. */
		timer.start(1000ms);
		dispatcher->interrupt();

		dispatcher->processEvents();

		if (!timer.isRunning()) {
			cout << "Event processing immediate interruption failed" << endl;
			return TestFail;
		}

		timer.start(1000ms);
		itimer.it_value.tv_usec = 500000;
		interrupt = true;
		setitimer(ITIMER_REAL, &itimer, nullptr);

		dispatcher->processEvents();

		if (!timer.isRunning()) {
			cout << "Event processing delayed interruption failed" << endl;
			return TestFail;
		}

		return TestPass;
	}

	void cleanup()
	{
	}
};

TEST_REGISTER(EventDispatcherTest)
s="hl com"> * get the same format after converting back to the V4L2 Format. */ V4L2PixelFormat v4l2FmtExpect = V4L2PixelFormat( V4L2_PIX_FMT_SBGGR8); bayerFmt = BayerFormat::fromV4L2PixelFormat(v4l2FmtExpect); V4L2PixelFormat v4l2Fmt = bayerFmt.toV4L2PixelFormat(); if (v4l2Fmt != v4l2FmtExpect) { cerr << "Expected: '" << v4l2FmtExpect.toString() << "' got: '" << v4l2Fmt.toString() << "'" << endl; return TestFail; } /* * Use an empty Bayer format and verify that no matching * V4L2PixelFormat is found. */ v4l2FmtExpect = V4L2PixelFormat(); bayerFmt = BayerFormat(); v4l2Fmt = bayerFmt.toV4L2PixelFormat(); if (v4l2Fmt != v4l2FmtExpect) { cerr << "Expected: empty V4L2PixelFormat got: '" << v4l2Fmt.toString() << "'" << endl; return TestFail; } /* * Check if we get the expected Bayer format BGGR8 * when we convert the V4L2PixelFormat (V4L2_PIX_FMT_SBGGR8) * to a Bayer format. */ bayerFmtExpect = BayerFormat(BayerFormat::BGGR, 8, BayerFormat::Packing::None); v4l2Fmt = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8); bayerFmt = BayerFormat::fromV4L2PixelFormat(v4l2Fmt); if (bayerFmt != bayerFmtExpect) { cerr << "Expected BayerFormat '" << bayerFmtExpect.toString() << "', got: '" << bayerFmt.toString() << "'" << endl; return TestFail; } /* * Confirm that a V4L2PixelFormat that is not found in * the conversion table, doesn't yield a Bayer format. */ V4L2PixelFormat v4l2FmtUnknown = V4L2PixelFormat( V4L2_PIX_FMT_BGRA444); bayerFmt = BayerFormat::fromV4L2PixelFormat(v4l2FmtUnknown); if (bayerFmt.isValid()) { cerr << "Expected empty BayerFormat got: '" << bayerFmt.toString() << "'" << endl; return TestFail; } /* * Test if a valid Bayer format can be converted to a * string representation. */ bayerFmt = BayerFormat(BayerFormat::BGGR, 8, BayerFormat::Packing::None); if (bayerFmt.toString() != "BGGR-8") { cerr << "String representation != 'BGGR-8' (got: '" << bayerFmt.toString() << "' ) " << endl; return TestFail; } /* * Determine if an empty Bayer format results in no * string representation. */ bayerFmt = BayerFormat(); if (bayerFmt.toString() != "INVALID") { cerr << "String representation != 'INVALID' (got: '" << bayerFmt.toString() << "' ) " << endl; return TestFail; } /* * Perform a horizontal Flip and make sure that the * order is adjusted accordingly. */ bayerFmt = BayerFormat(BayerFormat::BGGR, 8, BayerFormat::Packing::None); bayerFmtExpect = BayerFormat(BayerFormat::GBRG, 8, BayerFormat::Packing::None); BayerFormat hFlipFmt = bayerFmt.transform(Transform::HFlip); if (hFlipFmt != bayerFmtExpect) { cerr << "Horizontal flip of 'BGGR-8' should result in '" << bayerFmtExpect.toString() << "', got: '" << hFlipFmt.toString() << "'" << endl; return TestFail; } /* * Perform a vertical Flip and make sure that * the order is adjusted accordingly. */ bayerFmt = BayerFormat(BayerFormat::BGGR, 8, BayerFormat::Packing::None); bayerFmtExpect = BayerFormat(BayerFormat::GRBG, 8, BayerFormat::Packing::None); BayerFormat vFlipFmt = bayerFmt.transform(Transform::VFlip); if (vFlipFmt != bayerFmtExpect) { cerr << "Vertical flip of 'BGGR-8' should result in '" << bayerFmtExpect.toString() << "', got: '" << vFlipFmt.toString() << "'" << endl; return TestFail; } /* * Perform a transposition on a pixel order with both green * pixels on the bottom left to top right diagonal and make * sure, that it doesn't change. */ bayerFmt = BayerFormat(BayerFormat::BGGR, 8, BayerFormat::Packing::None); BayerFormat transposeFmt = bayerFmt.transform( Transform::Transpose); if (transposeFmt != bayerFmt) { cerr << "Transpose with both green pixels on the " << "antidiagonal should not change the order " << "(got '" << transposeFmt.toString() << "')" << endl; return TestFail; } /* * Perform a transposition on an pixel order with red and blue * on the bottom left to top right diagonal and make sure * that their positions are switched. */ bayerFmt = BayerFormat(BayerFormat::GBRG, 8, BayerFormat::Packing::None); bayerFmtExpect = BayerFormat(BayerFormat::GRBG, 8, BayerFormat::Packing::None); transposeFmt = bayerFmt.transform(Transform::Transpose); if (transposeFmt != bayerFmtExpect) { cerr << "Transpose with the red & blue pixels on the " << "antidiagonal should switch their position " << "(got '" << transposeFmt.toString() << "')" << endl; return TestFail; } return TestPass; } }; TEST_REGISTER(BayerFormatTest)