CVB++ 15.1
Loading...
Searching...
No Matches
detail_device_factory.hpp
1#pragma once
2
3#include "../_cexports/c_driver.h"
4#include "../_cexports/c_img.h"
5
6#include "../global.hpp"
7
8#include "../_decl/decl_device_factory.hpp"
9
10#include "../driver/_decl/decl_vin_device.hpp"
11#include "../driver/_decl/decl_emu_device.hpp"
12#include "../driver/_decl/decl_video_device.hpp"
13#include "../driver/_decl/decl_genicam_device.hpp"
14
15#include "../driver/non_streaming_device.hpp"
16
17namespace Cvb
18{
19
20 CVB_BEGIN_INLINE_NS
21
22 inline HandleGuard<Device> DeviceFactory::LoadAsGenTL(const String &provider, AcquisitionStack acquisitionStack)
23 {
24 CExports::DEVOBJ obj = nullptr;
25 if (AllowFallback(acquisitionStack))
26 {
27 CVB_CALL_CAPI(CVDCreateOrGetDeviceObjectTyped(provider.c_str(), obj));
28 }
29 else
30 {
31 CVB_CALL_CAPI_CHECKED(CVDCreateOrGetDeviceObjectTyped(provider.c_str(), obj));
32 }
33 return HandleGuard<Device>(obj);
34 }
35
36 inline HandleGuard<Device> DeviceFactory::LoadAsVin(const String &provider, AcquisitionStack acquisitionStack)
37 {
38 CExports::IMG img = nullptr;
39 if (AllowFallback(acquisitionStack))
40 {
41 CVB_CALL_CAPI(LoadImageFileTyped(provider.c_str(), img));
42 }
43 else
44 {
45 CVB_CALL_CAPI_CHECKED(LoadImageFileTyped(provider.c_str(), img));
46 }
47 return HandleGuard<Device>(img);
48 }
49
50 inline HandleGuard<Device> DeviceFactory::LoadAsNonStreaming(const String &provider)
51 {
52 CExports::DEVOBJ obj = nullptr;
53 CVB_CALL_CAPI_CHECKED(LoadDeviceObjectTyped(provider.c_str(), obj));
54 return HandleGuard<Device>(obj);
55 }
56
57 inline DevicePtr DeviceFactory::CreateDeviceByDriverGUID(const Cvb::String &provider,
58 Cvb::HandleGuard<Cvb::Device> &&guard) noexcept
59 {
60 using namespace Cvb;
61 CExports::cvbguid_t deviceGuid = {0};
62 CVB_CALL_CAPI_CHECKED(GetDriverID(guard.Handle(), deviceGuid));
63
64 if (Cvb::CExports::operator==(deviceGuid, DeviceFactory::AviMpgGuid()))
65 return Device::FromHandle<VideoDevice>(std::move(guard), provider);
66 else if (Cvb::CExports::operator==(deviceGuid, DeviceFactory::EmuGuid()))
67 return Device::FromHandle<EmuDevice>(std::move(guard), provider);
68 else
69 return Device::FromHandle<VinDevice>(std::move(guard), provider);
70 }
71
72 inline DevicePtr DeviceFactory::Open(const String &provider,
73 AcquisitionStack acquisitionStack /*= AcquisitionStack::PreferVin*/)
74 {
75 std::unique_lock<std::mutex> lock(LockAnchor());
76 switch (acquisitionStack)
77 {
78 case AcquisitionStack::Vin:
79 return CreateDeviceByDriverGUID(provider, LoadAsVin(provider, acquisitionStack));
80
81 case AcquisitionStack::PreferVin:
82 {
83 auto vinGuard = LoadAsVin(provider, acquisitionStack);
84 if (vinGuard.Handle())
85 return CreateDeviceByDriverGUID(provider, std::move(vinGuard));
86 return Device::FromHandle<NonStreamingDevice>(LoadAsNonStreaming(provider), provider);
87 }
88
89 case AcquisitionStack::GenTL:
90 return Device::FromHandle<GenICamDevice>(LoadAsGenTL(provider, acquisitionStack), provider);
91
92 case AcquisitionStack::PreferGenTL:
93 default:
94 {
95 auto gentlGuard = LoadAsGenTL(provider, acquisitionStack);
96 if (gentlGuard.Handle())
97 return Device::FromHandle<GenICamDevice>(std::move(gentlGuard), provider);
98 auto vinGuard = LoadAsVin(provider, acquisitionStack);
99 if (vinGuard.Handle())
100 return CreateDeviceByDriverGUID(provider, std::move(vinGuard));
101 return Device::FromHandle<NonStreamingDevice>(LoadAsNonStreaming(provider), provider);
102 }
103 }
104 }
105
107 {
108 return Open(info.AccessToken(), acquisitionStack);
109 }
110
111 template <class Rep, class Period>
113 DeviceFactory::Discover(const String &accessToken, Driver::DiscoverFlags flags,
115 {
116#ifdef max
117# undef max
118#endif
119
120 auto msTimeSpan = std::chrono::duration_cast<std::chrono::milliseconds>(timeSpan).count();
121 if (msTimeSpan > std::chrono::milliseconds::max().count())
122 throw std::overflow_error("discover timeout must fit to std::chrono::duration in ms");
123
124 CExports::ATLIST handle = nullptr;
125 auto discoverResult = CExports::DODiscoverTyped(accessToken.c_str(), static_cast<CExports::cvbuint64_t>(flags), 0,
126 handle, static_cast<size_t>(msTimeSpan));
127 if (discoverResult < 0)
128 std::rethrow_exception(CvbException::FromCvbResult(discoverResult, "failed to discover"));
129
130 Driver::DiscoveryInformation::List listHandle(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); });
131
132 std::size_t numEntries = 0;
133 auto numEntriesResult = CExports::DOGetNumEntries(listHandle.get(), numEntries);
134 if (numEntriesResult < 0)
136 CvbException::FromCvbResult(numEntriesResult, "failed to get number of entries for device object"));
137
138 std::vector<Driver::DiscoveryInformation> discoveryInformationVector;
139 discoveryInformationVector.reserve(numEntries);
140
141 for (size_t i = 0; i < numEntries; ++i)
142 discoveryInformationVector.emplace_back(Driver::DiscoveryInformation(listHandle, static_cast<int>(i)));
143
144 return discoveryInformationVector;
145 }
146
147 inline void DeviceFactory::ChangeBoard(DevicePtr &device, int board)
148 {
149 if (CExports::CanBoardSelect2(device->Handle()))
150 {
151 std::unique_lock<std::mutex> lock(LockAnchor());
152 ChangeBoard2(device, board);
153 }
154 else if (CExports::CanBoardSelect(device->Handle()))
155 {
156 std::unique_lock<std::mutex> lock(LockAnchor());
157 ChangeBoard1(device, board);
158 }
159 else
160 {
161 if (board == 0)
162 return;
163 else
164 std::rethrow_exception(CvbException::FromCvbResult(ErrorCodes::CVB_ERROR, "no IBoardSelect or IBoardSelect2"));
165 }
166 }
167
168 inline void DeviceFactory::ChangeBoard1(DevicePtr &device, int board)
169 {
170 CExports::cvbval_t currentBoard = 0;
171 auto getBoardResult = CExports::GetBoard(device->Handle(), &currentBoard);
172 if (getBoardResult < 0)
173 std::rethrow_exception(CvbException::FromCvbResult(getBoardResult, "no current board"));
174 if (static_cast<int>(currentBoard) == board)
175 return;
176
177 auto setBoardResult = CExports::SetBoard(device->Handle(), static_cast<CExports::cvbval_t>(board));
178 if (setBoardResult < 0)
179 std::rethrow_exception(CvbException::FromCvbResult(setBoardResult, "failed to set board"));
180 }
181
182 inline void DeviceFactory::ChangeBoard2(DevicePtr &device, int board)
183 {
184 CExports::cvbval_t currentBoard = 0;
185 auto getBoardResult = CExports::BS2GetBoard(device->Handle(), currentBoard);
186 if (getBoardResult < 0)
187 std::rethrow_exception(CvbException::FromCvbResult(getBoardResult, "no current board"));
188 if (static_cast<int>(currentBoard) == board)
189 return;
190 CExports::cvbval_t numBoards = 0;
191 auto numBoardsResult = CExports::BS2GetNumBoards(device->Handle(), numBoards);
192 if (numBoardsResult < 0)
193 std::rethrow_exception(CvbException::FromCvbResult(numBoardsResult, "no number of boards"));
194 if (board >= static_cast<int>(numBoards))
195 throw std::out_of_range("board out of range");
196
197 CExports::IMG newImg = nullptr;
198 auto setBoardResult = CExports::BS2SetBoard(device->Handle(), board, newImg);
199 if (setBoardResult < 0)
200 std::rethrow_exception(CvbException::FromCvbResult(setBoardResult, "failed to set board"));
201
202 HandleGuard<Device> guard(newImg);
203 device = Device::FromHandle<Driver::VinDevice>(std::move(guard), device->ResourceLocator());
204 }
205
206 inline void DeviceFactory::ChangePort(DevicePtr &device, int port)
207 {
208 if (CExports::CanCameraSelect2(device->Handle()))
209 {
210 std::unique_lock<std::mutex> lock(LockAnchor());
211 ChangePort2(device, port);
212 }
213 else if (CExports::CanCameraSelect(device->Handle()))
214 {
215 std::unique_lock<std::mutex> lock(LockAnchor());
216 ChangePort1(device, port);
217 }
218 else
219 {
220 if (port == 0)
221 return;
222 else
223 std::rethrow_exception(
224 CvbException::FromCvbResult(ErrorCodes::CVB_ERROR, "no ICameraSelect or ICameraSelect2"));
225 }
226 }
227
228 inline void DeviceFactory::ChangePort1(DevicePtr &device, int port)
229 {
230 CExports::cvbval_t currentPort = 0;
231 auto getPortResult = CExports::GetCamPort(device->Handle(), currentPort);
232 if (getPortResult < 0)
233 std::rethrow_exception(CvbException::FromCvbResult(getPortResult, "no current port"));
234 if (static_cast<int>(currentPort) == port)
235 return;
236 CExports::cvbval_t numPorts = 0;
237 auto numPortsResult = CExports::GetNumPorts(device->Handle(), numPorts);
238 if (numPortsResult < 0)
239 std::rethrow_exception(CvbException::FromCvbResult(numPortsResult, "no number of ports"));
240 if (port >= static_cast<int>(numPorts))
241 throw std::out_of_range("port out of range");
242
243 auto setPortResult = CExports::SetCamPort(device->Handle(), static_cast<CExports::cvbval_t>(port), 0);
244 if (setPortResult < 0)
245 std::rethrow_exception(CvbException::FromCvbResult(setPortResult, "failed to set port"));
246 }
247
248 inline void DeviceFactory::ChangePort2(DevicePtr &device, int port)
249 {
250 CExports::cvbval_t currentPort = 0;
251 auto getPortResult = CExports::CS2GetCamPort(device->Handle(), currentPort);
252 if (getPortResult < 0)
253 std::rethrow_exception(CvbException::FromCvbResult(getPortResult, "no current port"));
254 if (static_cast<int>(currentPort) == port)
255 return;
256 CExports::cvbval_t numPorts = 0;
257 auto numPortsResult = CExports::CS2GetNumPorts(device->Handle(), numPorts);
258 if (numPortsResult < 0)
259 std::rethrow_exception(CvbException::FromCvbResult(numPortsResult, "no number of ports"));
260 if (port >= static_cast<int>(numPorts))
261 throw std::out_of_range("port out of range");
262
263 CExports::IMG newImg = nullptr;
264 auto setPortResult = CExports::CS2SetCamPort(device->Handle(), static_cast<CExports::cvbval_t>(port), 0, newImg);
265 if (setPortResult < 0)
266 std::rethrow_exception(CvbException::FromCvbResult(setPortResult, "failed to set port"));
267
268 HandleGuard<Device> guard(newImg);
269 device = Device::FromHandle<Driver::VinDevice>(std::move(guard), device->ResourceLocator());
270 }
271
272 CVB_END_INLINE_NS
273
274} // namespace Cvb
static std::vector< DiscoveryInformation > Discover()
Discovers available devices (not vins) with a default time span of 300ms.
Definition decl_device_factory.hpp:263
static std::shared_ptr< T > Open(const String &provider, AcquisitionStack acquisitionStack=AcquisitionStack::PreferVin)
Opens a device with the given provider with its default board and port (if applicable).
Definition decl_device_factory.hpp:56
Stores information on a discovered device/node.
Definition discovery_information.hpp:26
String AccessToken() const
The access token for opening the device/node.
Definition discovery_information.hpp:105
T duration_cast(T... args)
cvbbool_t ReleaseObject(OBJ &Object)
T lock(T... args)
T move(T... args)
AcquisitionStack
Defines the acquisition stack when opening the device.
Definition driver.hpp:282
DiscoverFlags
Flags controlling the discovery process.
Definition driver.hpp:302
const int CVB_ERROR
Generic unspecified error.
Definition exception.hpp:23
Root namespace for the Image Manager interface.
Definition version.hpp:11
std::string String
String for wide characters or unicode characters.
Definition string.hpp:49
std::shared_ptr< Device > DevicePtr
Convenience shared pointer for Device.
Definition global.hpp:98
T rethrow_exception(T... args)