CVB++ 15.0
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 (deviceGuid == DeviceFactory::AviMpgGuid())
65 return Device::FromHandle<VideoDevice>(std::move(guard), provider);
66 else if (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
106 template <class Rep, class Period>
108 DeviceFactory::Discover(const String &accessToken, Driver::DiscoverFlags flags,
110 {
111#ifdef max
112# undef max
113#endif
114
115 auto msTimeSpan = std::chrono::duration_cast<std::chrono::milliseconds>(timeSpan).count();
116 if (msTimeSpan > std::chrono::milliseconds::max().count())
117 throw std::overflow_error("discover timeout must fit to std::chrono::duration in ms");
118
119 CExports::ATLIST handle = nullptr;
120 auto discoverResult = CExports::DODiscoverTyped(accessToken.c_str(), static_cast<CExports::cvbuint64_t>(flags), 0,
121 handle, static_cast<size_t>(msTimeSpan));
122 if (discoverResult < 0)
123 std::rethrow_exception(CvbException::FromCvbResult(discoverResult, "failed to discover"));
124
125 Driver::DiscoveryInformation::List listHandle(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); });
126
127 std::size_t numEntries = 0;
128 auto numEntriesResult = CExports::DOGetNumEntries(listHandle.get(), numEntries);
129 if (numEntriesResult < 0)
131 CvbException::FromCvbResult(numEntriesResult, "failed to get number of entries for device object"));
132
133 std::vector<Driver::DiscoveryInformation> discoveryInformationVector;
134 discoveryInformationVector.reserve(numEntries);
135
136 for (size_t i = 0; i < numEntries; ++i)
137 discoveryInformationVector.emplace_back(Driver::DiscoveryInformation(listHandle, static_cast<int>(i)));
138
139 return discoveryInformationVector;
140 }
141
142 inline void DeviceFactory::ChangeBoard(DevicePtr &device, int board)
143 {
144 if (CExports::CanBoardSelect2(device->Handle()))
145 {
146 std::unique_lock<std::mutex> lock(LockAnchor());
147 ChangeBoard2(device, board);
148 }
149 else if (CExports::CanBoardSelect(device->Handle()))
150 {
151 std::unique_lock<std::mutex> lock(LockAnchor());
152 ChangeBoard1(device, board);
153 }
154 else
155 {
156 if (board == 0)
157 return;
158 else
159 std::rethrow_exception(CvbException::FromCvbResult(ErrorCodes::CVB_ERROR, "no IBoardSelect or IBoardSelect2"));
160 }
161 }
162
163 inline void DeviceFactory::ChangeBoard1(DevicePtr &device, int board)
164 {
165 CExports::cvbval_t currentBoard = 0;
166 auto getBoardResult = CExports::GetBoard(device->Handle(), &currentBoard);
167 if (getBoardResult < 0)
168 std::rethrow_exception(CvbException::FromCvbResult(getBoardResult, "no current board"));
169 if (static_cast<int>(currentBoard) == board)
170 return;
171
172 auto setBoardResult = CExports::SetBoard(device->Handle(), static_cast<CExports::cvbval_t>(board));
173 if (setBoardResult < 0)
174 std::rethrow_exception(CvbException::FromCvbResult(setBoardResult, "failed to set board"));
175 }
176
177 inline void DeviceFactory::ChangeBoard2(DevicePtr &device, int board)
178 {
179 CExports::cvbval_t currentBoard = 0;
180 auto getBoardResult = CExports::BS2GetBoard(device->Handle(), currentBoard);
181 if (getBoardResult < 0)
182 std::rethrow_exception(CvbException::FromCvbResult(getBoardResult, "no current board"));
183 if (static_cast<int>(currentBoard) == board)
184 return;
185 CExports::cvbval_t numBoards = 0;
186 auto numBoardsResult = CExports::BS2GetNumBoards(device->Handle(), numBoards);
187 if (numBoardsResult < 0)
188 std::rethrow_exception(CvbException::FromCvbResult(numBoardsResult, "no number of boards"));
189 if (board >= static_cast<int>(numBoards))
190 throw std::out_of_range("board out of range");
191
192 CExports::IMG newImg = nullptr;
193 auto setBoardResult = CExports::BS2SetBoard(device->Handle(), board, newImg);
194 if (setBoardResult < 0)
195 std::rethrow_exception(CvbException::FromCvbResult(setBoardResult, "failed to set board"));
196
197 HandleGuard<Device> guard(newImg);
198 device = Device::FromHandle<Driver::VinDevice>(std::move(guard), device->ResourceLocator());
199 }
200
201 inline void DeviceFactory::ChangePort(DevicePtr &device, int port)
202 {
203 if (CExports::CanCameraSelect2(device->Handle()))
204 {
205 std::unique_lock<std::mutex> lock(LockAnchor());
206 ChangePort2(device, port);
207 }
208 else if (CExports::CanCameraSelect(device->Handle()))
209 {
210 std::unique_lock<std::mutex> lock(LockAnchor());
211 ChangePort1(device, port);
212 }
213 else
214 {
215 if (port == 0)
216 return;
217 else
218 std::rethrow_exception(
219 CvbException::FromCvbResult(ErrorCodes::CVB_ERROR, "no ICameraSelect or ICameraSelect2"));
220 }
221 }
222
223 inline void DeviceFactory::ChangePort1(DevicePtr &device, int port)
224 {
225 CExports::cvbval_t currentPort = 0;
226 auto getPortResult = CExports::GetCamPort(device->Handle(), currentPort);
227 if (getPortResult < 0)
228 std::rethrow_exception(CvbException::FromCvbResult(getPortResult, "no current port"));
229 if (static_cast<int>(currentPort) == port)
230 return;
231 CExports::cvbval_t numPorts = 0;
232 auto numPortsResult = CExports::GetNumPorts(device->Handle(), numPorts);
233 if (numPortsResult < 0)
234 std::rethrow_exception(CvbException::FromCvbResult(numPortsResult, "no number of ports"));
235 if (port >= static_cast<int>(numPorts))
236 throw std::out_of_range("port out of range");
237
238 auto setPortResult = CExports::SetCamPort(device->Handle(), static_cast<CExports::cvbval_t>(port), 0);
239 if (setPortResult < 0)
240 std::rethrow_exception(CvbException::FromCvbResult(setPortResult, "failed to set port"));
241 }
242
243 inline void DeviceFactory::ChangePort2(DevicePtr &device, int port)
244 {
245 CExports::cvbval_t currentPort = 0;
246 auto getPortResult = CExports::CS2GetCamPort(device->Handle(), currentPort);
247 if (getPortResult < 0)
248 std::rethrow_exception(CvbException::FromCvbResult(getPortResult, "no current port"));
249 if (static_cast<int>(currentPort) == port)
250 return;
251 CExports::cvbval_t numPorts = 0;
252 auto numPortsResult = CExports::CS2GetNumPorts(device->Handle(), numPorts);
253 if (numPortsResult < 0)
254 std::rethrow_exception(CvbException::FromCvbResult(numPortsResult, "no number of ports"));
255 if (port >= static_cast<int>(numPorts))
256 throw std::out_of_range("port out of range");
257
258 CExports::IMG newImg = nullptr;
259 auto setPortResult = CExports::CS2SetCamPort(device->Handle(), static_cast<CExports::cvbval_t>(port), 0, newImg);
260 if (setPortResult < 0)
261 std::rethrow_exception(CvbException::FromCvbResult(setPortResult, "failed to set port"));
262
263 HandleGuard<Device> guard(newImg);
264 device = Device::FromHandle<Driver::VinDevice>(std::move(guard), device->ResourceLocator());
265 }
266
267 CVB_END_INLINE_NS
268
269} // namespace Cvb
static std::vector< DiscoveryInformation > Discover()
Discovers available devices (not vins) with a default time span of 300ms.
Definition decl_device_factory.hpp:217
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
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 c_bayer_to_rgb.h:17
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)