/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2019, Google Inc. * * v4l2_compat.cpp - V4L2 compatibility layer */ #include "v4l2_compat_manager.h" #include #include #include #include #include #include #include #define LIBCAMERA_PUBLIC __attribute__((visibility("default"))) using namespace libcamera; #define extract_va_arg(type, arg, last) \ { \ va_list ap; \ va_start(ap, last); \ arg = va_arg(ap, type); \ va_end(ap); \ } extern "C" { LIBCAMERA_PUBLIC int open(const char *path, int oflag, ...) { mode_t mode = 0; if (oflag & O_CREAT || oflag & O_TMPFILE) extract_va_arg(mode_t, mode, oflag); return V4L2CompatManager::instance()->openat(AT_FDCWD, path, oflag, mode); } /* _FORTIFY_SOURCE redirects open to __open_2 */ LIBCAMERA_PUBLIC int __open_2(const char *path, int oflag) { return open(path, oflag); } #ifndef open64 LIBCAMERA_PUBLIC int open64(const char *path, int oflag, ...) { mode_t mode = 0; if (oflag & O_CREAT || oflag & O_TMPFILE) extract_va_arg(mode_t, mode, oflag); return V4L2CompatManager::instance()->openat(AT_FDCWD, path, oflag | O_LARGEFILE, mode); } LIBCAMERA_PUBLIC int __open64_2(const char *path, int oflag) { return open(path, oflag); } #endif LIBCAMERA_PUBLIC int openat(int dirfd, const char *path, int oflag, ...) { mode_t mode = 0; if (oflag & O_CREAT || oflag & O_TMPFILE) extract_va_arg(mode_t, mode, oflag); return V4L2CompatManager::instance()->openat(dirfd, path, oflag, mode); } LIBCAMERA_PUBLIC int __openat_2(int dirfd, const char *path, int oflag) { return openat(dirfd, path, oflag); } #ifndef openat64 LIBCAMERA_PUBLIC int openat64(int dirfd, const char *path, int oflag, ...) { mode_t mode = 0; if (oflag & O_CREAT || oflag & O_TMPFILE) extract_va_arg(mode_t, mode, oflag); return V4L2CompatManager::instance()->openat(dirfd, path, oflag | O_LARGEFILE, mode); } LIBCAMERA_PUBLIC int __openat64_2(int dirfd, const char *path, int oflag) { return openat(dirfd, path, oflag); } #endif LIBCAMERA_PUBLIC int dup(int oldfd) { return V4L2CompatManager::instance()->dup(oldfd); } LIBCAMERA_PUBLIC int close(int fd) { return V4L2CompatManager::instance()->close(fd); } LIBCAMERA_PUBLIC void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { return V4L2CompatManager::instance()->mmap(addr, length, prot, flags, fd, offset); } #ifndef mmap64 LIBCAMERA_PUBLIC void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset) { return V4L2CompatManager::instance()->mmap(addr, length, prot, flags, fd, offset); } #endif LIBCAMERA_PUBLIC int munmap(void *addr, size_t length) { return V4L2CompatManager::instance()->munmap(addr, length); } LIBCAMERA_PUBLIC int ioctl(int fd, unsigned long request, ...) { void *arg; extract_va_arg(void *, arg, request); return V4L2CompatManager::instance()->ioctl(fd, request, arg); } } a/libcamera.git/plain/src/lc-compliance/capture_test.cpp?h=v0.3.0&id=5faa0b1a2a00a2881a4a9babc0ee0d12adf08c4b'>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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2020, Google Inc.
 * Copyright (C) 2021, Collabora Ltd.
 *
 * capture_test.cpp - Test camera capture
 */

#include <iostream>

#include <gtest/gtest.h>

#include "environment.h"
#include "simple_capture.h"

using namespace libcamera;

const std::vector<int> NUMREQUESTS = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
const std::vector<StreamRole> ROLES = { Raw, StillCapture, VideoRecording, Viewfinder };

class SingleStream : public testing::TestWithParam<std::tuple<StreamRole, int>>
{
public:
	static std::string nameParameters(const testing::TestParamInfo<SingleStream::ParamType> &info);

protected:
	void SetUp() override;
	void TearDown() override;

	std::shared_ptr<Camera> camera_;
};

/*
 * We use gtest's SetUp() and TearDown() instead of constructor and destructor
 * in order to be able to assert on them.
 */
void SingleStream::SetUp()
{
	Environment *env = Environment::get();

	camera_ = env->cm()->get(env->cameraId());

	ASSERT_EQ(camera_->acquire(), 0);
}

void SingleStream::TearDown()
{
	if (!camera_)
		return;

	camera_->release();
	camera_.reset();
}

std::string SingleStream::nameParameters(const testing::TestParamInfo<SingleStream::ParamType> &info)
{
	std::map<StreamRole, std::string> rolesMap = { { Raw, "Raw" },
						       { StillCapture, "StillCapture" },
						       { VideoRecording, "VideoRecording" },
						       { Viewfinder, "Viewfinder" } };

	std::string roleName = rolesMap[std::get<0>(info.param)];
	std::string numRequestsName = std::to_string(std::get<1>(info.param));

	return roleName + "_" + numRequestsName;
}

/*
 * Test single capture cycles
 *
 * Makes sure the camera completes the exact number of requests queued. Example
 * failure is a camera that completes less requests than the number of requests
 * queued.
 */
TEST_P(SingleStream, Capture)
{
	auto [role, numRequests] = GetParam();

	SimpleCaptureBalanced capture(camera_);

	capture.configure(role);

	capture.capture(numRequests);
}

/*
 * Test multiple start/stop cycles
 *
 * Makes sure the camera supports multiple start/stop cycles. Example failure is
 * a camera that does not clean up correctly in its error path but is only
 * tested by single-capture applications.
 */
TEST_P(SingleStream, CaptureStartStop)
{
	auto [role, numRequests] = GetParam();
	unsigned int numRepeats = 3;

	SimpleCaptureBalanced capture(camera_);

	capture.configure(role);

	for (unsigned int starts = 0; starts < numRepeats; starts++)
		capture.capture(numRequests);
}

/*
 * Test unbalanced stop
 *
 * Makes sure the camera supports a stop with requests queued. Example failure
 * is a camera that does not handle cancelation of buffers coming back from the
 * video device while stopping.
 */
TEST_P(SingleStream, UnbalancedStop)
{
	auto [role, numRequests] = GetParam();

	SimpleCaptureUnbalanced capture(camera_);

	capture.configure(role);

	capture.capture(numRequests);
}

INSTANTIATE_TEST_SUITE_P(CaptureTests,
			 SingleStream,
			 testing::Combine(testing::ValuesIn(ROLES),
					  testing::ValuesIn(NUMREQUESTS)),
			 SingleStream::nameParameters);