summaryrefslogtreecommitdiff
path: root/src/libcamera/pipeline/raspberrypi/rpi_stream.h
blob: f42e25b93a351f1b26ddfc6fc7cb0efad428c724 (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
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2020, Raspberry Pi (Trading) Ltd.
 *
 * rpi_stream.h - Raspberry Pi device stream abstraction class.
 */
#ifndef __LIBCAMERA_PIPELINE_RPI_STREAM_H__
#define __LIBCAMERA_PIPELINE_RPI_STREAM_H__

#include <queue>
#include <string>
#include <vector>

#include <libcamera/stream.h>

#include "libcamera/internal/v4l2_videodevice.h"

namespace libcamera {

namespace RPi {

/*
 * Device stream abstraction for either an internal or external stream.
 * Used for both Unicam and the ISP.
 */
class RPiStream : public Stream
{
public:
	RPiStream()
	{
	}

	RPiStream(const char *name, MediaEntity *dev, bool importOnly = false)
		: external_(false), importOnly_(importOnly), name_(name),
		  dev_(std::make_unique<V4L2VideoDevice>(dev))
	{
	}

	V4L2VideoDevice *dev() const;
	std::string name() const;
	bool isImporter() const;
	void reset();

	void setExternal(bool external);
	bool isExternal() const;

	void setExportedBuffers(std::vector<std::unique_ptr<FrameBuffer>> *buffers);
	const std::vector<FrameBuffer *> &getBuffers() const;
	bool findFrameBuffer(FrameBuffer *buffer) const;

	int prepareBuffers(unsigned int count);
	int queueBuffer(FrameBuffer *buffer);
	void returnBuffer(FrameBuffer *buffer);

	int queueAllBuffers();
	void releaseBuffers();

private:
	void clearBuffers();
	int queueToDevice(FrameBuffer *buffer);

	/*
	 * Indicates that this stream is active externally, i.e. the buffers
	 * might be provided by (and returned to) the application.
	 */
	bool external_;

	/* Indicates that this stream only imports buffers, e.g. ISP input. */
	bool importOnly_;

	/* Stream name identifier. */
	std::string name_;

	/* The actual device stream. */
	std::unique_ptr<V4L2VideoDevice> dev_;

	/* All frame buffers associated with this device stream. */
	std::vector<FrameBuffer *> bufferList_;

	/*
	 * List of frame buffers that we can use if none have been provided by
	 * the application for external streams. This is populated by the
	 * buffers exported internally.
	 */
	std::queue<FrameBuffer *> availableBuffers_;

	/*
	 * List of frame buffers that are to be queued into the device from a Request.
	 * A nullptr indicates any internal buffer can be used (from availableBuffers_),
	 * whereas a valid pointer indicates an external buffer to be queued.
	 *
	 * Ordering buffers to be queued is important here as it must match the
	 * requests coming from the application.
	 */
	std::queue<FrameBuffer *> requestBuffers_;

	/*
	 * This is a list of buffers exported internally. Need to keep this around
	 * as the stream needs to maintain ownership of these buffers.
	 */
	std::vector<std::unique_ptr<FrameBuffer>> internalBuffers_;
};

/*
 * The following class is just a convenient (and typesafe) array of device
 * streams indexed with an enum class.
 */
template<typename E, std::size_t N>
class RPiDevice : public std::array<class RPiStream, N>
{
private:
	constexpr auto index(E e) const noexcept
	{
		return static_cast<std::underlying_type_t<E>>(e);
	}
public:
	RPiStream &operator[](E e)
	{
		return std::array<class RPiStream, N>::operator[](index(e));
	}
	const RPiStream &operator[](E e) const
	{
		return std::array<class RPiStream, N>::operator[](index(e));
	}
};

} /* namespace RPi */

} /* namespace libcamera */

#endif /* __LIBCAMERA_PIPELINE_RPI_STREAM_H__ */