#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <cvb/composite.hpp>
#include <cvb/device_factory.hpp>
#include <cvb/driver/driver.hpp>
#include <cvb/driver/image_stream.hpp>
#include <cvb/global.hpp>
#include <cvb/image.hpp>
#include <cvb/utilities/utilities.hpp>
static const constexpr auto TIMEOUT = std::chrono::milliseconds(3000);
static const constexpr int NUM_ELEMENTS_TO_ACQUIRE = 10;
static const constexpr int NUM_BUFFERS = 4;
namespace helper {
static inline void *aligned_alloc(size_t alignment, size_t size) noexcept {
#ifdef _MSC_VER
return _aligned_malloc(size, alignment);
#else
void *memptr = nullptr;
return !posix_memalign(&memptr, alignment, size)
? memptr
: nullptr;
#endif
}
static inline void free(void *ptr) noexcept {
#ifdef _MSC_VER
_aligned_free(ptr);
#else
free(ptr);
#endif
}
class UserFlowSetPool final : public Cvb::Driver::FlowSetPool {
using UserFlowSetPoolPtr = std::shared_ptr<UserFlowSetPool>;
public:
UserFlowSetPool(const std::vector<Cvb::FlowInfo> &flowInfo) noexcept
: Cvb::FlowSetPool(flowInfo, Cvb::FlowSetPool::ProtectedTag{}) {}
virtual ~UserFlowSetPool() {
for (auto &flowSet : *this)
for (auto &flow : flowSet)
helper::free(flow.Buffer);
}
static UserFlowSetPoolPtr
Create(const std::vector<Cvb::FlowInfo> &flowInfos) {
return std::make_shared<UserFlowSetPool>(flowInfos);
}
};
}
for (auto i = 0; i < NUM_ELEMENTS_TO_ACQUIRE; i++) {
auto [composite, waitStatus, enumerator] = stream->WaitFor(TIMEOUT);
switch (waitStatus) {
default:
std::cout << "wait status unknown.\n";
case Cvb::WaitStatus::Abort:
case Cvb::WaitStatus::Timeout: {
std::cout << "wait status not ok\n";
continue;
}
case Cvb::WaitStatus::Ok: {
break;
}
}
auto firstElement = composite->ItemAt(0);
if (!Cvb::holds_alternative<Cvb::ImagePtr>(firstElement)) {
std::cout << "composite does not contain an image at the first element\n";
continue;
}
auto image = Cvb::get<Cvb::ImagePtr>(firstElement);
auto linearAccess =
image->Plane(0).LinearAccess();
std::cout << "acquired image: " << i << " at memory location: "
<< reinterpret_cast<intptr_t>(linearAccess.BasePtr()) << "\n";
}
}
int main() {
try {
auto infoList =
if (infoList.empty())
throw std::runtime_error(
"There is no available device for this demonstration.");
infoList[0].AccessToken(), Cvb::AcquisitionStack::GenTL);
if (device->StreamCount() == 0)
throw std::runtime_error(
"There is no available stream for this demonstration.");
auto flowSetPoolPtr = helper::UserFlowSetPool::Create(flowSetInfo);
std::generate_n(
std::back_inserter(*flowSetPoolPtr), NUM_BUFFERS, [&flowSetInfo]() {
auto flows = std::vector<void *>(flowSetInfo.size());
std::transform(
flowSetInfo.begin(), flowSetInfo.end(), flows.begin(),
void *memptr = helper::aligned_alloc(info.Alignment, info.Size);
if (!memptr)
throw std::runtime_error("Failed to allocate a memory.");
return memptr;
});
return flows;
});
stream->RegisterExternalFlowSetPool(std::move(flowSetPoolPtr));
stream->EngineStart();
stream->DeviceStart();
AcquireData(stream);
stream->DeviceAbort();
stream->EngineAbort();
stream->DeregisterFlowSetPool();
} catch (const std::exception &e) {
std::cout << e.what() << std::endl;
}
return 0;
}
std::vector< FlowInfo > FlowSetInfo() const
static std::vector< DiscoveryInformation > Discover()
static std::shared_ptr< T > Open(const String &provider, AcquisitionStack acquisitionStack=AcquisitionStack::PreferVin)
std::shared_ptr< CompositeStream > CompositeStreamPtr