CVB++ 15.0
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#include "../gendc_descriptor.hpp"
13
14namespace Cvb
15{
16
17 CVB_BEGIN_INLINE_NS
18
19 template <>
20 inline HandleGuard<CompositeStreamBase>::HandleGuard(void *handle) noexcept
21 : HandleGuard<CompositeStreamBase>(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
22 {
23 }
24
25 namespace Driver
26 {
27
29
30 class CompositeStreamBase : public StreamBase
31 {
32 public:
33 using GuardType = HandleGuard<CompositeStreamBase>;
34
35 template <class T, class... ARGS>
36 static std::shared_ptr<T> FromHandle(HandleGuard<CompositeStreamBase> &&guard, ARGS &&...args);
37
39
45 void *Handle() const noexcept
46 {
47 return handle_.Handle();
48 }
49
51
56 virtual void EngineStart()
57 {
58 EngineStart(-1);
59 }
60
62
69 virtual void EngineStart(std::int64_t bufferCountToAcquire)
70 {
71 Internal::DoResCall([this, bufferCountToAcquire]() {
72 return CExports::CVDStreamAcquisitionEngineStart(Handle(), bufferCountToAcquire);
73 });
74 acquisitionState_ = Cvb::AcquisitionState::Started;
75 }
76
78
86 template <class Rep, class Period>
88 {
90 }
91
93
98 virtual void EngineStop()
99 {
100 InternalEngineStop(std::chrono::milliseconds(-1));
101 }
102
104
111 template <class Rep, class Period>
116
118
124 virtual bool TryEngineStop() noexcept
125 {
127 }
128
130
137 virtual bool TryEngineStop(const std::chrono::milliseconds &timeout) noexcept
138 {
139 if (acquisitionState_ == Cvb::AcquisitionState::Started)
140 acquisitionState_ = Cvb::AcquisitionState::Stopping;
141 auto result = CExports::CVDStreamAcquisitionEngineStop(Handle(), timeout.count()) == ErrorCodes::CVB_OK;
142 if (result)
143 acquisitionState_ = Cvb::AcquisitionState::Stopped;
144 return result;
145 }
146
148
159 virtual void EngineAbort()
160 {
161 if (acquisitionState_ == Cvb::AcquisitionState::Started)
162 acquisitionState_ = Cvb::AcquisitionState::Stopping;
163 else if (acquisitionState_ == Cvb::AcquisitionState::Stopping)
164 acquisitionState_ = Cvb::AcquisitionState::AbortingStop;
165 Internal::DoResCall([this]() { return CExports::CVDStreamAcquisitionEngineAbort(Handle()); });
166 acquisitionState_ = Cvb::AcquisitionState::Stopped;
167 }
168
170
176 virtual bool TryEngineAbort() noexcept
177 {
178 if (acquisitionState_ == Cvb::AcquisitionState::Started)
179 acquisitionState_ = Cvb::AcquisitionState::Stopping;
180 else if (acquisitionState_ == Cvb::AcquisitionState::Stopping)
181 acquisitionState_ = Cvb::AcquisitionState::AbortingStop;
182 auto result = CExports::CVDStreamAcquisitionEngineAbort(Handle()) == ErrorCodes::CVB_OK;
183 if (result)
184 acquisitionState_ = Cvb::AcquisitionState::Stopped;
185 return result;
186 }
187
189
193 virtual void DeviceStart()
194 {
195 DeviceStart(-1);
196 }
197
199
205 virtual void DeviceStart(std::int64_t bufferCountToAcquire)
206 {
207 Internal::DoResCall(
208 [this, bufferCountToAcquire]() { return CExports::CVDStreamControlStart(Handle(), bufferCountToAcquire); });
209 }
210
212
218 virtual void DeviceStop()
219 {
220 Internal::DoResCall([this]() { return CExports::CVDStreamControlStop(Handle()); });
221 }
222
224
230 virtual bool TryDeviceStop() noexcept
231 {
232 return CExports::CVDStreamControlStop(Handle()) == ErrorCodes::CVB_OK;
233 }
234
236
242 virtual void DeviceAbort()
243 {
244 Internal::DoResCall([this]() { return CExports::CVDStreamControlAbort(Handle()); });
245 }
246
248
254 virtual bool TryDeviceAbort() noexcept
255 {
256 return CExports::CVDStreamControlAbort(Handle()) == ErrorCodes::CVB_OK;
257 }
258
260
267 {
268 CVB_CALL_CAPI_CHECKED(CVDStreamUnregisterFlowSetPool(Handle()));
269 }
270
272
280 void RegisterManagedFlowSetPool(int flowSetCount)
281 {
282 CVB_CALL_CAPI_CHECKED(CVDStreamRegisterManagedFlowSetPool(Handle(), static_cast<std::size_t>(flowSetCount)));
283 }
284
286
290 {
291 RegisterExternalFlowSetPool(flowSetPoolPtr, []() {});
292 }
293
295
299 void RegisterExternalFlowSetPool(FlowSetPoolPtr flowSetPoolPtr, std::function<void()> releaseCallback)
300 {
301 flowSetPoolPtr->SetUserCallback(releaseCallback);
302 CVB_CALL_CAPI_CHECKED(CVDStreamRegisterExternalFlowSetPool(
303 Handle(), reinterpret_cast<CExports::CVDFlowSet *>(flowSetPoolPtr->ToNativeStruct().data()),
304 flowSetPoolPtr->PoolSize(), flowSetPoolPtr->OnReleaseCallback, &*flowSetPoolPtr));
305 flowSetPoolPtr->SetReleaseThis(flowSetPoolPtr);
306 }
307
309
314 int FlowSetCount() const noexcept
315 {
316 std::size_t count = 0;
317 CVB_CALL_CAPI(CVDStreamGetFlowSetCount(Handle(), count));
318 return static_cast<int>(count);
319 }
320
322
329 {
330 std::size_t count = 0;
331 CVB_CALL_CAPI(CVDStreamFlowSetInfoGetFlowSetMinCount(Handle(), count));
332 return static_cast<int>(count);
333 }
334
339
340 void Start() override
341 {
342 EngineStart();
343 DeviceStart();
344 combinedStreaming_ = true;
345 }
346
347 void Stop() override
348 {
349 DeviceStop();
350 EngineStop();
351 combinedStreaming_ = false;
352 }
353
354 bool TryStop() noexcept override
355 {
356 auto deviceResult = TryDeviceStop();
357 auto engineResult = TryEngineStop();
358 combinedStreaming_ = false;
359 return deviceResult && engineResult;
360 }
361
362 void Abort() override
363 {
364 DeviceAbort();
365 EngineAbort();
366 combinedStreaming_ = false;
367 }
368
369 bool TryAbort() noexcept override
370 {
371 auto deviceResult = TryDeviceAbort();
372 auto engineResult = TryEngineAbort();
373 combinedStreaming_ = false;
374 return deviceResult && engineResult;
375 }
376
377 bool IsIndexed() const noexcept override
378 {
379 return false;
380 }
381
383
388 {
389 return acquisitionState_;
390 }
391
393
398 {
399 if (!CExports::CVDCanGenDCDescriptorProvider(Handle()))
400 throw std::runtime_error("Stream does not represent a GenDC stream");
401
402 return Internal::DoResCallObjectOut<Driver::GenDcDescriptor>([this](CExports::CVDGNDCDESCRIPTOR &handle) {
403 return CVB_CALL_CAPI(CVDGNDCPGetDescriptor(Handle(), handle));
404 });
405 }
406
408
413 {
414 if (!CExports::CVDCanFlowSetInfo(Handle()))
415 throw std::runtime_error("Stream has no flow set info");
416
417 // Get the flow count
418 std::size_t flowCount = 0;
419 CVB_CALL_CAPI_CHECKED(CVDStreamFlowSetInfoGetFlowCount(Handle(), flowCount));
420
421 std::vector<FlowInfo> flowInfos(flowCount);
422 for (std::size_t i = 0; i < flowCount; ++i)
423 {
424 CVB_CALL_CAPI_CHECKED(CVDStreamFlowSetInfoGetFlowSize(Handle(), i, flowInfos[i].Size));
425 CVB_CALL_CAPI_CHECKED(CVDStreamFlowSetInfoGetFlowAlignment(Handle(), i, flowInfos[i].Alignment));
426 }
427
428 return flowInfos;
429 }
430
432
445 NodeMapPtr NodeMap(const String &name) const;
446
448
454
455 CompositeStreamBase(const CompositeStreamBase &other) = delete;
456 CompositeStreamBase &operator=(const CompositeStreamBase &other) = delete;
458 CompositeStreamBase &operator=(CompositeStreamBase &&other) = delete;
459 virtual ~CompositeStreamBase()
460 {
461 if (combinedStreaming_)
462 {
463 // duplicate TryAbort() avoid virtual dispatch bypass
464 CExports::CVDStreamControlAbort(Handle());
465 CExports::CVDStreamAcquisitionEngineAbort(Handle());
466 }
467 }
468
469 protected:
470 template <class T>
471 using WaitResultBase = std::tuple<HandleGuard<T>, WaitStatus>;
472
473 explicit CompositeStreamBase(const DevicePtr &device, HandleGuard<CompositeStreamBase> &&guard)
474 : StreamBase(device)
475 , handle_(std::move(guard))
476 , acquisitionState_(Cvb::AcquisitionState::Stopped)
477 , combinedStreaming_(false)
478 {
479 if (CExports::CanNodeMapHandle2(Handle()))
480 TryFillNodeMapKeys2();
481 }
482
483 template <class T, class Rep, class Period>
484 WaitResultBase<T> InternalWaitFor(const std::chrono::duration<Rep, Period> &timeSpan)
485 {
486 return InternalWaitFor<T>(std::chrono::duration_cast<std::chrono::milliseconds>(timeSpan).count());
487 }
488
489 template <class T, class Rep, class Period>
490 WaitResultBase<T> InternalWaitFor(const std::chrono::duration<Rep, Period> &timeSpan,
491 const CancellationToken &token)
492 {
493 return InternalWaitFor<T>(std::chrono::duration_cast<std::chrono::milliseconds>(timeSpan).count(),
494 token.Handle());
495 }
496
497 template <class T>
498 WaitResultBase<T> InternalWait()
499 {
500 return InternalWaitFor<T>(-1);
501 }
502
503 template <class T>
504 WaitResultBase<T> InternalWait(const CancellationToken &token)
505 {
506 return InternalWaitFor<T>(-1, token.Handle());
507 }
508
509 private:
510 template <class T>
511 WaitResultBase<T> InternalWaitFor(std::int64_t timeout, CExports::CVCANCELLATIONTOKEN token = nullptr)
512 {
513 CExports::CVDWaitStatus waitStatus = CExports::CVDWaitStatus::CVDWS_Ok;
514 CExports::CVCOMPOSITE handle = nullptr;
515 CVB_CALL_CAPI_CHECKED(
516 CVDStreamAcquisitionEngineWaitForNextComposite(Handle(), timeout, token, waitStatus, handle));
517 return std::make_tuple(HandleGuard<T>(handle), static_cast<WaitStatus>(waitStatus));
518 }
519
520 virtual void InternalEngineStop(const std::chrono::milliseconds &timeout)
521 {
522 if (acquisitionState_ == Cvb::AcquisitionState::Started)
523 acquisitionState_ = Cvb::AcquisitionState::Stopping;
524 Internal::DoResCall(
525 [this, timeout]() { return CExports::CVDStreamAcquisitionEngineStop(Handle(), timeout.count()); });
526 acquisitionState_ = Cvb::AcquisitionState::Stopped;
527 }
528
529 bool TryFillNodeMapKeys2()
530 {
531 size_t numNodeMaps = 0;
532 auto resultNum = CExports::NMH2GetNum(Handle(), numNodeMaps);
533 if (resultNum < 0)
534 return false;
535 for (size_t i = 0; i < numNodeMaps; ++i)
536 {
537 size_t bufferSize = 0;
538 auto resultBufferLength = CExports::NMH2GetID(Handle(), i, nullptr, bufferSize);
539 if (resultBufferLength < 0)
540 continue;
541 std::vector<char> buffer(bufferSize);
542 auto resultBuffer = CExports::NMH2GetID(Handle(), i, &buffer[0], bufferSize);
543 if (resultBuffer < 0)
544 continue;
545 String keyString(buffer.begin(), buffer.end() - 1);
546 nodeMaps_[keyString].Reset();
547 }
548 return true;
549 }
550
551 HandleGuard<CompositeStreamBase> handle_;
552 std::atomic<Cvb::AcquisitionState> acquisitionState_;
553 mutable std::map<String, Internal::AsyncRef<GenApi::NodeMap>> nodeMaps_;
554 bool combinedStreaming_;
555 };
556
557 } // namespace Driver
558
560
561 CVB_END_INLINE_NS
562
563} // namespace Cvb
Base class of all composite based streams.
Definition decl_composite_stream_base.hpp:31
Base class of all composite based streams.
Definition decl_composite_stream_base.hpp:31
void Abort() override
Stops the acquisition of images immediately.
Definition decl_composite_stream_base.hpp:362
void Start() override
Starts the acquisition.
Definition decl_composite_stream_base.hpp:340
virtual void EngineStart(std::int64_t bufferCountToAcquire)
Starts the acquisition engine on the host.
Definition decl_composite_stream_base.hpp:69
Cvb::Driver::AcquisitionInterface AcquisitionInterface() const noexcept override
Gets the interface of this implementation.
Definition decl_composite_stream_base.hpp:335
virtual bool TryEngineAbort() noexcept
Stops the acquisition engine immediately.
Definition decl_composite_stream_base.hpp:176
void DeregisterFlowSetPool()
Removes an existing flow set pool from the acquisition engine.
Definition decl_composite_stream_base.hpp:266
virtual bool TryEngineStop() noexcept
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:124
void RegisterManagedFlowSetPool(int flowSetCount)
Registers an internal flows set pool.
Definition decl_composite_stream_base.hpp:280
virtual bool TryDeviceStop() noexcept
Stops the stream in the device.
Definition decl_composite_stream_base.hpp:230
void Stop() override
Stops the acquisition.
Definition decl_composite_stream_base.hpp:347
virtual void DeviceStart(std::int64_t bufferCountToAcquire)
Starts the stream on the device.
Definition decl_composite_stream_base.hpp:205
virtual void DeviceStop()
Stops the stream in the device.
Definition decl_composite_stream_base.hpp:218
void EngineStop(const std::chrono::duration< Rep, Period > &timeout)
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:87
bool IsIndexed() const noexcept override
Gets whether this stream is an indexed stream.
Definition decl_composite_stream_base.hpp:377
Cvb::AcquisitionState AcquisitionState() const noexcept
Gets the current acquisition state.
Definition decl_composite_stream_base.hpp:387
int MinRequiredFlowSetCount() const
Gets minimum number of flow sets required for the acquisition.
Definition decl_composite_stream_base.hpp:328
bool TryAbort() noexcept override
Stops the acquisition of images immediately.
Definition decl_composite_stream_base.hpp:369
virtual void EngineStop()
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:98
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:242
virtual void DeviceStart()
Starts the stream on the device.
Definition decl_composite_stream_base.hpp:193
void RegisterExternalFlowSetPool(FlowSetPoolPtr flowSetPoolPtr)
Registers external memory.
Definition decl_composite_stream_base.hpp:289
bool TryEngineStop(const std::chrono::duration< Rep, Period > &timeout) noexcept
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:112
virtual void EngineStart()
Starts the acquisition engine on the host.
Definition decl_composite_stream_base.hpp:56
int FlowSetCount() const noexcept
Gets the number of registered flow sets.
Definition decl_composite_stream_base.hpp:314
virtual void EngineAbort()
Stops the acquisition engine immediately.
Definition decl_composite_stream_base.hpp:159
std::unique_ptr< Driver::GenDcDescriptor > GenDCPrefetchDescriptor() const
If this Stream represents a GenDC stream, returns the GenDC prefetch descriptor.
Definition decl_composite_stream_base.hpp:397
virtual bool TryDeviceAbort() noexcept
Stops the stream in the device immediately.
Definition decl_composite_stream_base.hpp:254
std::vector< FlowInfo > FlowSetInfo() const
Gets the flow set info of this stream.
Definition decl_composite_stream_base.hpp:412
void * Handle() const noexcept
Classic API stream handle.
Definition decl_composite_stream_base.hpp:45
bool TryStop() noexcept override
Stops the acquisition.
Definition decl_composite_stream_base.hpp:354
void RegisterExternalFlowSetPool(FlowSetPoolPtr flowSetPoolPtr, std::function< void()> releaseCallback)
Registers external memory.
Definition decl_composite_stream_base.hpp:299
virtual bool TryEngineStop(const std::chrono::milliseconds &timeout) noexcept
Stops the acquisition engine.
Definition decl_composite_stream_base.hpp:137
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:28
std::shared_ptr< FlowSetPool > FlowSetPoolPtr
Convenience shared pointer for FlowSetPool.
Definition driver.hpp:33
@ String
String value.
Definition driver.hpp:366
AcquisitionState
Specifies current state of the acquisition engine.
Definition driver.hpp:542
@ Stopped
The engine is stopped.
Definition driver.hpp:550
AcquisitionInterface
Known acquisition CVB interfaces.
Definition driver.hpp:435
@ GenTL
Flow set pool / queue based acquition for TL based techologies.
Definition driver.hpp:441
const int CVB_OK
No error occurred.
Definition exception.hpp:21
std::shared_ptr< NodeMap > NodeMapPtr
Convenience shared pointer for NodeMap.
Definition genapi.hpp:27
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