CVB++ 15.0
Loading...
Searching...
No Matches
decl_composite_stream_base.hpp
1#pragma once
2
3#include <memory>
4#include <atomic>
5
6#include "../stream_base.hpp"
7#include "../driver.hpp"
8#include "../../exception.hpp"
9#include "../../cancellation_token.hpp"
10#include "../../genapi/node_map_enumerator.hpp"
11#include "../flow_set_pool.hpp"
12
13namespace Cvb
14{
15
16 CVB_BEGIN_INLINE_NS
17
18 template <>
19 inline HandleGuard<CompositeStreamBase>::HandleGuard(void *handle) noexcept
20 : HandleGuard<CompositeStreamBase>(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
21 {
22 }
23
24 namespace Driver
25 {
26
28
29 class CompositeStreamBase : public StreamBase
30 {
31 public:
32 using GuardType = HandleGuard<CompositeStreamBase>;
33
34 template <class T, class... ARGS>
35 static std::shared_ptr<T> FromHandle(HandleGuard<CompositeStreamBase> &&guard, ARGS &&...args);
36
38
44 void *Handle() const noexcept
45 {
46 return handle_.Handle();
47 }
48
50
55 virtual void EngineStart()
56 {
57 EngineStart(-1);
58 }
59
61
68 virtual void EngineStart(std::int64_t bufferCountToAcquire)
69 {
70 Internal::DoResCall([this, bufferCountToAcquire]() {
71 return CExports::CVDStreamAcquisitionEngineStart(Handle(), bufferCountToAcquire);
72 });
73 acquisitionState_ = Cvb::AcquisitionState::Started;
74 }
75
77
85 template <class Rep, class Period>
87 {
89 }
90
92
97 virtual void EngineStop()
98 {
99 InternalEngineStop(std::chrono::milliseconds(-1));
100 }
101
103
110 template <class Rep, class Period>
115
117
123 virtual bool TryEngineStop() noexcept
124 {
126 }
127
129
136 virtual bool TryEngineStop(const std::chrono::milliseconds &timeout) noexcept
137 {
138 if (acquisitionState_ == Cvb::AcquisitionState::Started)
139 acquisitionState_ = Cvb::AcquisitionState::Stopping;
140 auto result = CExports::CVDStreamAcquisitionEngineStop(Handle(), timeout.count()) == ErrorCodes::CVB_OK;
141 if (result)
142 acquisitionState_ = Cvb::AcquisitionState::Stopped;
143 return result;
144 }
145
147
158 virtual void EngineAbort()
159 {
160 if (acquisitionState_ == Cvb::AcquisitionState::Started)
161 acquisitionState_ = Cvb::AcquisitionState::Stopping;
162 else if (acquisitionState_ == Cvb::AcquisitionState::Stopping)
163 acquisitionState_ = Cvb::AcquisitionState::AbortingStop;
164 Internal::DoResCall([this]() { return CExports::CVDStreamAcquisitionEngineAbort(Handle()); });
165 acquisitionState_ = Cvb::AcquisitionState::Stopped;
166 }
167
169
175 virtual bool TryEngineAbort() noexcept
176 {
177 if (acquisitionState_ == Cvb::AcquisitionState::Started)
178 acquisitionState_ = Cvb::AcquisitionState::Stopping;
179 else if (acquisitionState_ == Cvb::AcquisitionState::Stopping)
180 acquisitionState_ = Cvb::AcquisitionState::AbortingStop;
181 auto result = CExports::CVDStreamAcquisitionEngineAbort(Handle()) == ErrorCodes::CVB_OK;
182 if (result)
183 acquisitionState_ = Cvb::AcquisitionState::Stopped;
184 return result;
185 }
186
188
192 virtual void DeviceStart()
193 {
194 DeviceStart(-1);
195 }
196
198
204 virtual void DeviceStart(std::int64_t bufferCountToAcquire)
205 {
206 Internal::DoResCall(
207 [this, bufferCountToAcquire]() { return CExports::CVDStreamControlStart(Handle(), bufferCountToAcquire); });
208 }
209
211
217 virtual void DeviceStop()
218 {
219 Internal::DoResCall([this]() { return CExports::CVDStreamControlStop(Handle()); });
220 }
221
223
229 virtual bool TryDeviceStop() noexcept
230 {
231 return CExports::CVDStreamControlStop(Handle()) == ErrorCodes::CVB_OK;
232 }
233
235
241 virtual void DeviceAbort()
242 {
243 Internal::DoResCall([this]() { return CExports::CVDStreamControlAbort(Handle()); });
244 }
245
247
253 virtual bool TryDeviceAbort() noexcept
254 {
255 return CExports::CVDStreamControlAbort(Handle()) == ErrorCodes::CVB_OK;
256 }
257
259
266 {
267 CVB_CALL_CAPI_CHECKED(CVDStreamUnregisterFlowSetPool(Handle()));
268 }
269
271
279 void RegisterManagedFlowSetPool(int flowSetCount)
280 {
281 CVB_CALL_CAPI_CHECKED(CVDStreamRegisterManagedFlowSetPool(Handle(), static_cast<std::size_t>(flowSetCount)));
282 }
283
285
289 {
290 RegisterExternalFlowSetPool(flowSetPoolPtr, []() {});
291 }
292
294
298 void RegisterExternalFlowSetPool(FlowSetPoolPtr flowSetPoolPtr, std::function<void()> releaseCallback)
299 {
300 flowSetPoolPtr->SetUserCallback(releaseCallback);
301 CVB_CALL_CAPI_CHECKED(CVDStreamRegisterExternalFlowSetPool(
302 Handle(), reinterpret_cast<CExports::CVDFlowSet *>(flowSetPoolPtr->ToNativeStruct().data()),
303 flowSetPoolPtr->PoolSize(), flowSetPoolPtr->OnReleaseCallback, &*flowSetPoolPtr));
304 flowSetPoolPtr->SetReleaseThis(flowSetPoolPtr);
305 }
306
308
313 int FlowSetCount() const noexcept
314 {
315 std::size_t count = 0;
316 CVB_CALL_CAPI(CVDStreamGetFlowSetCount(Handle(), count));
317 return static_cast<int>(count);
318 }
319
321
328 {
329 std::size_t count = 0;
330 CVB_CALL_CAPI(CVDStreamFlowSetInfoGetFlowSetMinCount(Handle(), count));
331 return static_cast<int>(count);
332 }
333
338
339 void Start() override
340 {
341 EngineStart();
342 DeviceStart();
343 combinedStreaming_ = true;
344 }
345
346 void Stop() override
347 {
348 DeviceStop();
349 EngineStop();
350 combinedStreaming_ = false;
351 }
352
353 bool TryStop() noexcept override
354 {
355 auto deviceResult = TryDeviceStop();
356 auto engineResult = TryEngineStop();
357 combinedStreaming_ = false;
358 return deviceResult && engineResult;
359 }
360
361 void Abort() override
362 {
363 DeviceAbort();
364 EngineAbort();
365 combinedStreaming_ = false;
366 }
367
368 bool TryAbort() noexcept override
369 {
370 auto deviceResult = TryDeviceAbort();
371 auto engineResult = TryEngineAbort();
372 combinedStreaming_ = false;
373 return deviceResult && engineResult;
374 }
375
376 bool IsIndexed() const noexcept override
377 {
378 return false;
379 }
380
382
387 {
388 return acquisitionState_;
389 }
390
392
397 {
398 if (!CExports::CVDCanFlowSetInfo(Handle()))
399 throw std::runtime_error("Stream has no flow set info");
400
401 // Get the flow count
402 std::size_t flowCount = 0;
403 CVB_CALL_CAPI_CHECKED(CVDStreamFlowSetInfoGetFlowCount(Handle(), flowCount));
404
405 std::vector<FlowInfo> flowInfos(flowCount);
406 for (std::size_t i = 0; i < flowCount; ++i)
407 {
408 CVB_CALL_CAPI_CHECKED(CVDStreamFlowSetInfoGetFlowSize(Handle(), i, flowInfos[i].Size));
409 CVB_CALL_CAPI_CHECKED(CVDStreamFlowSetInfoGetFlowAlignment(Handle(), i, flowInfos[i].Alignment));
410 }
411
412 return flowInfos;
413 }
414
416
429 NodeMapPtr NodeMap(const String &name) const;
430
432
438
439 CompositeStreamBase(const CompositeStreamBase &other) = delete;
440 CompositeStreamBase &operator=(const CompositeStreamBase &other) = delete;
442 CompositeStreamBase &operator=(CompositeStreamBase &&other) = delete;
443 virtual ~CompositeStreamBase()
444 {
445 if (combinedStreaming_)
446 {
447 // duplicate TryAbort() avoid virtual dispatch bypass
448 CExports::CVDStreamControlAbort(Handle());
449 CExports::CVDStreamAcquisitionEngineAbort(Handle());
450 }
451 }
452
453 protected:
454 template <class T>
455 using WaitResultBase = std::tuple<HandleGuard<T>, WaitStatus>;
456
457 explicit CompositeStreamBase(const DevicePtr &device, HandleGuard<CompositeStreamBase> &&guard)
458 : StreamBase(device)
459 , handle_(std::move(guard))
460 , acquisitionState_(Cvb::AcquisitionState::Stopped)
461 , combinedStreaming_(false)
462 {
463 if (CExports::CanNodeMapHandle2(Handle()))
464 TryFillNodeMapKeys2();
465 }
466
467 template <class T, class Rep, class Period>
468 WaitResultBase<T> InternalWaitFor(const std::chrono::duration<Rep, Period> &timeSpan)
469 {
470 return InternalWaitFor<T>(std::chrono::duration_cast<std::chrono::milliseconds>(timeSpan).count());
471 }
472
473 template <class T, class Rep, class Period>
474 WaitResultBase<T> InternalWaitFor(const std::chrono::duration<Rep, Period> &timeSpan,
475 const CancellationToken &token)
476 {
477 return InternalWaitFor<T>(std::chrono::duration_cast<std::chrono::milliseconds>(timeSpan).count(),
478 token.Handle());
479 }
480
481 template <class T>
482 WaitResultBase<T> InternalWait()
483 {
484 return InternalWaitFor<T>(-1);
485 }
486
487 template <class T>
488 WaitResultBase<T> InternalWait(const CancellationToken &token)
489 {
490 return InternalWaitFor<T>(-1, token.Handle());
491 }
492
493 private:
494 template <class T>
495 WaitResultBase<T> InternalWaitFor(std::int64_t timeout, CExports::CVCANCELLATIONTOKEN token = nullptr)
496 {
497 CExports::CVDWaitStatus waitStatus = CExports::CVDWaitStatus::CVDWS_Ok;
498 CExports::CVCOMPOSITE handle = nullptr;
499 CVB_CALL_CAPI_CHECKED(
500 CVDStreamAcquisitionEngineWaitForNextComposite(Handle(), timeout, token, waitStatus, handle));
501 return std::make_tuple(HandleGuard<T>(handle), static_cast<WaitStatus>(waitStatus));
502 }
503
504 virtual void InternalEngineStop(const std::chrono::milliseconds &timeout)
505 {
506 if (acquisitionState_ == Cvb::AcquisitionState::Started)
507 acquisitionState_ = Cvb::AcquisitionState::Stopping;
508 Internal::DoResCall(
509 [this, timeout]() { return CExports::CVDStreamAcquisitionEngineStop(Handle(), timeout.count()); });
510 acquisitionState_ = Cvb::AcquisitionState::Stopped;
511 }
512
513 bool TryFillNodeMapKeys2()
514 {
515 size_t numNodeMaps = 0;
516 auto resultNum = CExports::NMH2GetNum(Handle(), numNodeMaps);
517 if (resultNum < 0)
518 return false;
519 for (size_t i = 0; i < numNodeMaps; ++i)
520 {
521 size_t bufferSize = 0;
522 auto resultBufferLength = CExports::NMH2GetID(Handle(), i, nullptr, bufferSize);
523 if (resultBufferLength < 0)
524 continue;
525 std::vector<char> buffer(bufferSize);
526 auto resultBuffer = CExports::NMH2GetID(Handle(), i, &buffer[0], bufferSize);
527 if (resultBuffer < 0)
528 continue;
529 String keyString(buffer.begin(), buffer.end() - 1);
530 nodeMaps_[keyString].Reset();
531 }
532 return true;
533 }
534
535 HandleGuard<CompositeStreamBase> handle_;
536 std::atomic<Cvb::AcquisitionState> acquisitionState_;
537 mutable std::map<String, Internal::AsyncRef<GenApi::NodeMap>> nodeMaps_;
538 bool combinedStreaming_;
539 };
540
541 } // namespace Driver
542
544
545 CVB_END_INLINE_NS
546
547} // namespace Cvb
Base class of all composite based streams.
Definition decl_composite_stream_base.hpp:30
Base class of all composite based streams.
Definition decl_composite_stream_base.hpp:30
void Abort() override
Stops the acquisition of images immediately.
Definition decl_composite_stream_base.hpp:361
void Start() override
Starts the acquisition.
Definition decl_composite_stream_base.hpp:339
virtual void EngineStart(std::int64_t bufferCountToAcquire)
Starts the acquisition engine on the host.
Definition decl_composite_stream_base.hpp:68
Cvb::Driver::AcquisitionInterface AcquisitionInterface() const noexcept override
Gets the interface of this implementation.
Definition decl_composite_stream_base.hpp:334
virtual bool TryEngineAbort() noexcept
Stops the acquisition engine immediately.
Definition decl_composite_stream_base.hpp:175
void DeregisterFlowSetPool()
Removes an existing flow set pool from the acquisition engine.
Definition decl_composite_stream_base.hpp:265
virtual bool TryEngineStop() noexcept
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:123
void RegisterManagedFlowSetPool(int flowSetCount)
Registers an internal flows set pool.
Definition decl_composite_stream_base.hpp:279
virtual bool TryDeviceStop() noexcept
Stops the stream in the device.
Definition decl_composite_stream_base.hpp:229
void Stop() override
Stops the acquisition.
Definition decl_composite_stream_base.hpp:346
virtual void DeviceStart(std::int64_t bufferCountToAcquire)
Starts the stream on the device.
Definition decl_composite_stream_base.hpp:204
virtual void DeviceStop()
Stops the stream in the device.
Definition decl_composite_stream_base.hpp:217
void EngineStop(const std::chrono::duration< Rep, Period > &timeout)
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:86
bool IsIndexed() const noexcept override
Gets whether this stream is an indexed stream.
Definition decl_composite_stream_base.hpp:376
Cvb::AcquisitionState AcquisitionState() const noexcept
Gets the current acquisition state.
Definition decl_composite_stream_base.hpp:386
int MinRequiredFlowSetCount() const
Gets minimum number of flow sets required for the acquisition.
Definition decl_composite_stream_base.hpp:327
bool TryAbort() noexcept override
Stops the acquisition of images immediately.
Definition decl_composite_stream_base.hpp:368
virtual void EngineStop()
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:97
NodeMapPtr NodeMap(const String &name) const
Gets the NodeMap with the given name.
Definition detail_composite_stream_base.hpp:24
virtual void DeviceAbort()
Stops the stream in the device immediately.
Definition decl_composite_stream_base.hpp:241
virtual void DeviceStart()
Starts the stream on the device.
Definition decl_composite_stream_base.hpp:192
void RegisterExternalFlowSetPool(FlowSetPoolPtr flowSetPoolPtr)
Registers external memory.
Definition decl_composite_stream_base.hpp:288
bool TryEngineStop(const std::chrono::duration< Rep, Period > &timeout) noexcept
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:111
virtual void EngineStart()
Starts the acquisition engine on the host.
Definition decl_composite_stream_base.hpp:55
int FlowSetCount() const noexcept
Gets the number of registered flow sets.
Definition decl_composite_stream_base.hpp:313
virtual void EngineAbort()
Stops the acquisition engine immediately.
Definition decl_composite_stream_base.hpp:158
virtual bool TryDeviceAbort() noexcept
Stops the stream in the device immediately.
Definition decl_composite_stream_base.hpp:253
std::vector< FlowInfo > FlowSetInfo() const
Gets the flow set info of this stream.
Definition decl_composite_stream_base.hpp:396
void * Handle() const noexcept
Classic API stream handle.
Definition decl_composite_stream_base.hpp:44
bool TryStop() noexcept override
Stops the acquisition.
Definition decl_composite_stream_base.hpp:353
void RegisterExternalFlowSetPool(FlowSetPoolPtr flowSetPoolPtr, std::function< void()> releaseCallback)
Registers external memory.
Definition decl_composite_stream_base.hpp:298
virtual bool TryEngineStop(const std::chrono::milliseconds &timeout) noexcept
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:136
std::map< String, NodeMapPtr > NodeMaps() const
Gets the dictionary holding all available stream NodeMaps.
Definition detail_composite_stream_base.hpp:40
T count(T... args)
T duration_cast(T... args)
cvbbool_t ReleaseObject(OBJ &Object)
Namespace for driver or device related operations.
Definition decl_composite.hpp:27
std::shared_ptr< FlowSetPool > FlowSetPoolPtr
Convenience shared pointer for FlowSetPool.
Definition driver.hpp:28
@ String
String value.
Definition driver.hpp:368
AcquisitionState
Specifies current state of the acquisition engine.
Definition driver.hpp:544
@ Stopped
The engine is stopped.
Definition driver.hpp:552
AcquisitionInterface
Known acquisition CVB interfaces.
Definition driver.hpp:437
@ GenTL
Flow set pool / queue based acquition for TL based techologies.
Definition driver.hpp:443
const int CVB_OK
No error occurred.
Definition exception.hpp:21
std::shared_ptr< NodeMap > NodeMapPtr
Convenience shared pointer for NodeMap.
Definition genapi.hpp:22
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
WaitStatus
Status after waiting for an image to be returned.
Definition global.hpp:396
std::shared_ptr< Device > DevicePtr
Convenience shared pointer for Device.
Definition global.hpp:98