#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <cstdlib>
#include <cvb/device_factory.hpp>
#include <cvb/global.hpp>
#include <cvb/driver/driver.hpp>
#include <cvb/image.hpp>
#include <cvb/composite.hpp>
#include <cvb/utilities/utilities.hpp>
#include <cvb/driver/image_stream.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);
{
std::cout << "composite does not contain an image at the first element\n";
continue;
}
auto linearAccess =
image->Plane(0).LinearAccess();
std::cout << "acquired image: " << i << " at memory location: " << reinterpret_cast<intptr_t>(linearAccess.BasePtr()) << "\n";
}
}
int main()
{
try
{
if (infoList.empty())
throw std::runtime_error("There is no available device for this demonstration.");
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());
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
const variant_alternative_t< I, variant< TS... > > & get(const variant< TS... > &var)
bool holds_alternative(const variant< TS... > &var) noexcept