summaryrefslogtreecommitdiff
path: root/src/ipa/vimc/vimc.cpp
blob: 85afb279ccf2ebd294b73a51a54450c83ad31ca0 (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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * ipa_vimc.cpp - Vimc Image Processing Algorithm module
 */
#include <libcamera/ipa/vimc_ipa_interface.h>

#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <iostream>

#include <libcamera/base/file.h>
#include <libcamera/base/log.h>

#include <libcamera/ipa/ipa_interface.h>
#include <libcamera/ipa/ipa_module_info.h>

#include "libcamera/internal/mapped_framebuffer.h"

namespace libcamera {

LOG_DEFINE_CATEGORY(IPAVimc)

class IPAVimc : public ipa::vimc::IPAVimcInterface
{
public:
	IPAVimc();
	~IPAVimc();

	int init(const IPASettings &settings) override;

	int start() override;
	void stop() override;

	int configure(const IPACameraSensorInfo &sensorInfo,
		      const std::map<unsigned int, IPAStream> &streamConfig,
		      const std::map<unsigned int, ControlInfoMap> &entityControls) override;

	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
	void unmapBuffers(const std::vector<unsigned int> &ids) override;

	void queueRequest(uint32_t frame, const ControlList &controls) override;
	void fillParamsBuffer(uint32_t frame, uint32_t bufferId) override;

private:
	void initTrace();
	void trace(enum ipa::vimc::IPAOperationCode operation);

	int fd_;
	std::map<unsigned int, MappedFrameBuffer> buffers_;
};

IPAVimc::IPAVimc()
	: fd_(-1)
{
	initTrace();
}

IPAVimc::~IPAVimc()
{
	if (fd_ != -1)
		::close(fd_);
}

int IPAVimc::init(const IPASettings &settings)
{
	trace(ipa::vimc::IPAOperationInit);

	LOG(IPAVimc, Debug)
		<< "initializing vimc IPA with configuration file "
		<< settings.configurationFile;

	File conf(settings.configurationFile);
	if (!conf.open(File::OpenModeFlag::ReadOnly)) {
		LOG(IPAVimc, Error) << "Failed to open configuration file";
		return -EINVAL;
	}

	return 0;
}

int IPAVimc::start()
{
	trace(ipa::vimc::IPAOperationStart);

	LOG(IPAVimc, Debug) << "start vimc IPA!";

	return 0;
}

void IPAVimc::stop()
{
	trace(ipa::vimc::IPAOperationStop);

	LOG(IPAVimc, Debug) << "stop vimc IPA!";
}

int IPAVimc::configure([[maybe_unused]] const IPACameraSensorInfo &sensorInfo,
			[[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig,
			[[maybe_unused]] const std::map<unsigned int, ControlInfoMap> &entityControls)
{
	LOG(IPAVimc, Debug) << "configure()";

	return 0;
}

void IPAVimc::mapBuffers(const std::vector<IPABuffer> &buffers)
{
	for (const IPABuffer &buffer : buffers) {
		const FrameBuffer fb(buffer.planes);
		buffers_.emplace(std::piecewise_construct,
				 std::forward_as_tuple(buffer.id),
				 std::forward_as_tuple(&fb, MappedFrameBuffer::MapFlag::Read));
	}
}

void IPAVimc::unmapBuffers(const std::vector<unsigned int> &ids)
{
	for (unsigned int id : ids) {
		auto it = buffers_.find(id);
		if (it == buffers_.end())
			continue;

		buffers_.erase(it);
	}
}

void IPAVimc::queueRequest([[maybe_unused]] uint32_t frame,
			   [[maybe_unused]] const ControlList &controls)
{
}

void IPAVimc::fillParamsBuffer([[maybe_unused]] uint32_t frame, uint32_t bufferId)
{
	auto it = buffers_.find(bufferId);
	if (it == buffers_.end()) {
		LOG(IPAVimc, Error) << "Could not find parameter buffer";
		return;
	}

	paramsBufferReady.emit(bufferId);
}

void IPAVimc::initTrace()
{
	struct stat fifoStat;
	int ret = stat(ipa::vimc::VimcIPAFIFOPath.c_str(), &fifoStat);
	if (ret)
		return;

	ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY);
	if (ret < 0) {
		ret = errno;
		LOG(IPAVimc, Error) << "Failed to open vimc IPA test FIFO: "
				    << strerror(ret);
		return;
	}

	fd_ = ret;
}

void IPAVimc::trace(enum ipa::vimc::IPAOperationCode operation)
{
	if (fd_ < 0)
		return;

	int ret = ::write(fd_, &operation, sizeof(operation));
	if (ret < 0) {
		ret = errno;
		LOG(IPAVimc, Error) << "Failed to write to vimc IPA test FIFO: "
				    << strerror(ret);
	}
}

/*
 * External IPA module interface
 */

extern "C" {
const struct IPAModuleInfo ipaModuleInfo = {
	IPA_MODULE_API_VERSION,
	0,
	"PipelineHandlerVimc",
	"vimc",
};

IPAInterface *ipaCreate()
{
	return new IPAVimc();
}
}

} /* namespace libcamera */
/span>FrameBuffer *> bufferReady; int streamOn(); int streamOff(); static V4L2VideoDevice *fromEntityName(const MediaDevice *media, const std::string &entity); static PixelFormat toPixelFormat(uint32_t v4l2Fourcc); uint32_t toV4L2Fourcc(PixelFormat pixelFormat); static uint32_t toV4L2Fourcc(PixelFormat pixelFormat, bool multiplanar); protected: std::string logPrefix() const; private: int getFormatMeta(V4L2DeviceFormat *format); int setFormatMeta(V4L2DeviceFormat *format); int getFormatMultiplane(V4L2DeviceFormat *format); int setFormatMultiplane(V4L2DeviceFormat *format); int getFormatSingleplane(V4L2DeviceFormat *format); int setFormatSingleplane(V4L2DeviceFormat *format); std::vector<unsigned int> enumPixelformats(); std::vector<SizeRange> enumSizes(unsigned int pixelFormat); int setSelection(unsigned int target, Rectangle *rect); int requestBuffers(unsigned int count); std::unique_ptr<FrameBuffer> createBuffer(const struct v4l2_buffer &buf); FileDescriptor exportDmabufFd(unsigned int index, unsigned int plane); void bufferAvailable(EventNotifier *notifier); FrameBuffer *dequeueBuffer(); V4L2Capability caps_; enum v4l2_buf_type bufferType_; enum v4l2_memory memoryType_; V4L2BufferCache *cache_; std::map<unsigned int, FrameBuffer *> queuedBuffers_; EventNotifier *fdEvent_; }; class V4L2M2MDevice { public: V4L2M2MDevice(const std::string &deviceNode); ~V4L2M2MDevice(); int open(); void close(); V4L2VideoDevice *output() { return output_; } V4L2VideoDevice *capture() { return capture_; } private: std::string deviceNode_; V4L2VideoDevice *output_; V4L2VideoDevice *capture_; }; } /* namespace libcamera */ #endif /* __LIBCAMERA_V4L2_VIDEODEVICE_H__ */