CVB++ 14.1
Cvb/CppMultiStream
1// ----------------------------------------------------------------------------
11// ----------------------------------------------------------------------------
12
13#include <iostream>
14#include <chrono>
15
16#include <cvb/device_factory.hpp>
17#include <cvb/image.hpp>
18#include <cvb/global.hpp>
19
20// Constants:
21static const constexpr auto TIMEOUT = std::chrono::milliseconds(3000);
22static const constexpr int NUM_ELEMENTS_TO_ACQUIRE = 10;
23
24static std::map<Cvb::WaitStatus, const char*> WAIT_ERROR_STATES{ {Cvb::WaitStatus::Timeout, "Timeout"},
25 {Cvb::WaitStatus::Abort, "Abort"} };
26
27int main(int argc, char* argv[])
28{
29 try
30 {
31 // Check if it is requested to run with a mock GenTL Producer.
32 bool demonstrateWithMock =
33 ((argc > 1) && (std::string(argv[1]).find("--mock") != std::string::npos)) ? true : false;
34
35 // Configure the discovery flags.
36 auto discoverFlags = Cvb::DiscoverFlags::IgnoreVins; // Ignores all of the CVB VINs.
37
38 // If it is requested to run with a mock, then additionally set an appropriate flag.
39 if (demonstrateWithMock)
40 discoverFlags |= Cvb::DiscoverFlags::IncludeMockTL; // Include CVMockTL.
41
42 // Retrieve a device.
43 auto infoList = Cvb::DeviceFactory::Discover(discoverFlags);
44
45 // Can't continue the demo if there's no device:
46 if (infoList.empty())
47 throw std::runtime_error("No devices found.");
48
49 // Determine the target device.
50 Cvb::String accessToken;
51
52 if (demonstrateWithMock)
53 {
54 for (auto n = 0; (n < infoList.size()) && accessToken.empty(); ++n)
55 if (infoList.at(n).AccessToken().find("MockTL") != std::string::npos)
56 accessToken = infoList.at(n).AccessToken();
57
58 // Make sure if CVMockTL is on the candidate list.
59 if (accessToken.empty())
60 throw std::runtime_error("Could not find CVMockTL.");
61 }
62 else
63 accessToken = infoList.front().AccessToken();
64
65 // Open the selected device.
66 auto device =
67 Cvb::DeviceFactory::Open<Cvb::GenICamDevice>(infoList.front().AccessToken(), Cvb::AcquisitionStack::GenTL);
68
69 // Get all streams that belong to the device.
71 std::generate_n(std::back_inserter(streams), device->StreamCount(),
72 [&device, i = 0]() mutable { return device->Stream<Cvb::ImageStream>(i++); });
73 std::cout << "Stream count: " << streams.size() << "\n";
74
75 // Let all streams start data streaming.
76 for (const auto stream : streams)
77 stream->Start();
78
79 // Acquire data.
80 // Note: Getting the data is sequential here for simplicity;
81 // concurrent wait on different streams is the more likely use case.
82 for (auto imageIndex = 0; imageIndex < NUM_ELEMENTS_TO_ACQUIRE; ++imageIndex)
83 {
84 for (auto streamIndex = 0u; streamIndex < streams.size(); ++streamIndex)
85 {
86 const auto stream = streams[streamIndex];
87 Cvb::ImagePtr image;
88 Cvb::WaitStatus waitStatus;
90 std::tie(image, waitStatus, nodeMaps) = stream->WaitFor(TIMEOUT);
91
92 switch (waitStatus)
93 {
94 default:
95 std::cout << "Unknown wait status.\n";
98 {
99 std::cout << "Wait status not OK: " << WAIT_ERROR_STATES[waitStatus] << "\n";
100 continue;
101 }
103 break;
104 }
105
106 std::cout << "Stream #" << streamIndex << ", Image #" << imageIndex;
107 std::cout << std::hex << ", Width: " << image->Width() <<
108 ", Height: " << image->Height() << "\n";
109 }
110 }
111
112 // Terminate the streaming.
113 for (const auto stream : streams)
114 stream->TryAbort();
115 }
116 catch (const std::exception& error)
117 {
118 std::cout << error.what() << std::endl;
119 }
120 return 0;
121}
122
static std::vector< DiscoveryInformation > Discover()
Discovers available devices (not vins) with a default time span of 300ms.
Definition: decl_device_factory.hpp:221
Lazy enumeration of node maps.
Definition: node_map_enumerator.hpp:31
WaitStatus
Status after waiting for an image to be returned.
Definition: global.hpp:376
@ Abort
The acquisition has been stopped asynchronously, there is no image buffer.
@ Ok
Everything is fine, a new image arrived.
@ Timeout
A timeout occurred, no image buffer has been returned.