/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2020, Google Inc. * * A provider of external buffers, suitable for use in tests. */ #include "buffer_source.h" #include #include #include "libcamera/internal/device_enumerator.h" #include "test.h" using namespace libcamera; BufferSource::BufferSource() { } BufferSource::~BufferSource() { if (media_) media_->release(); } int BufferSource::allocate(const StreamConfiguration &config) { /* Locate and open the video device. */ std::string videoDeviceName = "vivid-000-vid-out"; std::unique_ptr enumerator = DeviceEnumerator::create(); if (!enumerator) { std::cout << "Failed to create device enumerator" << std::endl; return TestFail; } if (enumerator->enumerate()) { std::cout << "Failed to enumerate media devices" << std::endl; return TestFail; } DeviceMatch dm("vivid"); dm.add(videoDeviceName); media_ = enumerator->search(dm); if (!media_) { std::cout << "No vivid output device available" << std::endl; return TestSkip; } std::unique_ptr video = V4L2VideoDevice::fromEntityName(media_.get(), videoDeviceName); if (!video) { std::cout << "Failed to get video device from entity " << videoDeviceName << std::endl; return TestFail; } if (video->open()) { std::cout << "Unable to open " << videoDeviceName << std::endl; return TestFail; } /* Configure the format. */ V4L2DeviceFormat format; if (video->getFormat(&format)) { std::cout << "Failed to get format on output device" << std::endl; return TestFail; } format.size = config.size; format.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat); if (video->setFormat(&format)) { std::cout << "Failed to set format on output device" << std::endl; return TestFail; } if (video->allocateBuffers(config.bufferCount, &buffers_) < 0) { std::cout << "Failed to allocate buffers" << std::endl; return TestFail; } video->close(); return TestPass; } const std::vector> &BufferSource::buffers() { return buffers_; } mit/include/libcamera/internal/pipeline_handler.h?h=rpi/streams/next&id=e52729e7ec3f735b0078b70e25e5daf2e051c429'>commitdiff
blob: 20f1cbb07fead07654276d9d88e228392e4cf932 (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
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2018, Google Inc.
 *
 * pipeline_handler.h - Pipeline handler infrastructure
 */

#pragma once

#include <memory>
#include <queue>
#include <set>
#include <string>
#include <sys/types.h>
#include <vector>

#include <libcamera/base/mutex.h>
#include <libcamera/base/object.h>

#include <libcamera/controls.h>
#include <libcamera/stream.h>

#include "libcamera/internal/ipa_proxy.h"

namespace libcamera {

class Camera;
class CameraConfiguration;
class CameraManager;
class DeviceEnumerator;
class DeviceMatch;
class FrameBuffer;
class MediaDevice;
class PipelineHandler;
class Request;

class PipelineHandler : public std::enable_shared_from_this<PipelineHandler>,
			public Object
{
public:
	PipelineHandler(CameraManager *manager);
	virtual ~PipelineHandler();

	virtual bool match(DeviceEnumerator *enumerator) = 0;
	MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator,
					const DeviceMatch &dm);

	bool acquire();
	void release();

	virtual CameraConfiguration *generateConfiguration(Camera *camera,
		const StreamRoles &roles) = 0;
	virtual int configure(Camera *camera, CameraConfiguration *config) = 0;

	virtual int exportFrameBuffers(Camera *camera, Stream *stream,
				       std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;

	virtual int start(Camera *camera, const ControlList *controls) = 0;
	void stop(Camera *camera);
	bool hasPendingRequests(const Camera *camera) const;

	void registerRequest(Request *request);
	void queueRequest(Request *request);

	bool completeBuffer(Request *request, FrameBuffer *buffer);
	void completeRequest(Request *request);

	const char *name() const { return name_; }

protected:
	void registerCamera(std::shared_ptr<Camera> camera);
	void hotplugMediaDevice(MediaDevice *media);

	virtual int queueRequestDevice(Camera *camera, Request *request) = 0;
	virtual void stopDevice(Camera *camera) = 0;

	CameraManager *manager_;

private:
	void unlockMediaDevices();

	void mediaDeviceDisconnected(MediaDevice *media);
	virtual void disconnect();

	void doQueueRequest(Request *request);
	void doQueueRequests();

	std::vector<std::shared_ptr<MediaDevice>> mediaDevices_;
	std::vector<std::weak_ptr<Camera>> cameras_;

	std::queue<Request *> waitingRequests_;

	const char *name_;

	Mutex lock_;
	unsigned int useCount_ LIBCAMERA_TSA_GUARDED_BY(lock_);

	friend class PipelineHandlerFactory;
};

class PipelineHandlerFactory
{
public:
	PipelineHandlerFactory(const char *name);
	virtual ~PipelineHandlerFactory() = default;

	std::shared_ptr<PipelineHandler> create(CameraManager *manager);

	const std::string &name() const { return name_; }

	static void registerType(PipelineHandlerFactory *factory);