eGrabber for MultiCam users
Concepts
MultiCam | eGrabber |
---|---|
Board | Interface |
Channel | Device + Data stream |
Surface | Buffer |
Surface cluster (MC_Cluster) | Buffers announced to the data stream |
- | Remote device (camera) |
MultiCam parameters | GenApi set/get features |
- | GenApi commands |
CAM file | Euresys GenApi script |
- | CallbackOnDemand |
Callback functions | CallbackSingleThread |
- | CallbackMultiThread |
Initialization
MultiCam:
MCSTATUS status = McOpenDriver(NULL);
if (status != MC_OK) {
...
}
eGrabber:
Euresys::EGenTL gentl;
Channel creation
MultiCam:
MCSTATUS status;
MCHANDLE channel;
status = McCreate(MC_CHANNEL, &handle);
if (status != MC_OK) {
...
}
status = McSetParamInt(channel, MC_DriverIndex, CARD_INDEX);
if (status != MC_OK) {
...
}
status = McSetParamInt(channel, MC_Connector, CONNECTOR);
if (status != MC_OK) {
...
}
eGrabber:
Euresys::EGrabber<> grabber(gentl, CARD_INDEX, DEVICE_INDEX);
Surface creation (automatic)
MultiCam:
status = McSetParamInt(channel, MC_SurfaceCount, BUFFER_COUNT);
if (status != MC_OK) {
...
}
eGrabber:
grabber.reallocBuffers(BUFFER_COUNT);
Surface creation (manual)
MultiCam:
for (size_t i = 0; i < BUFFER_COUNT; ++i) {
MCHANDLE surface;
MCSTATUS status;
void *mem = malloc(BUFFER_SIZE);
if (!mem) {
...
}
status = McCreate(MC_DEFAULT_SURFACE_HANDLE, &surface);
if (status != MC_OK) {
...
}
status = McSetParamInt(surface, MC_SurfaceSize, BUFFER_SIZE);
if (status != MC_OK) {
...
}
status = McSetParamPtr(surface, MC_SurfaceAddr, mem);
if (status != MC_OK) {
...
}
status = McSetParamPtr(surface, MC_SurfaceContext, USER_PTR[i]);
if (status != MC_OK) {
...
}
status = McSetParamInst(channel, MC_Cluster + i, surface);
if (status != MC_OK) {
...
}
}
eGrabber:
for (size_t i = 0; i < BUFFER_COUNT; ++i) {
void *mem = malloc(BUFFER_SIZE);
if (!mem) {
...
}
grabber.announceAndQueue(Euresys::UserMemory(mem, BUFFER_SIZE, USER_PTR[i]));
}
Surface cluster reset
MultiCam:
MCSTATUS status;
for (size_t i = 0; i < BUFFER_COUNT; ++i) {
MCHANDLE surface;
status = McGetParamInst(channel, MC_Cluster + i, &surface);
if (status != MC_OK) {
...
}
status = McSetParamInt(surface, MC_SurfaceState, MC_SurfaceState_FREE);
if (status != MC_OK) {
...
}
}
status = McSetParamInt(channel, MC_SurfaceIndex, 0);
if (status != MC_OK) {
...
}
eGrabber:
grabber.resetBufferQueue();
Frame grabber configuration
MultiCam | eGrabber |
---|---|
McSetParamStr(H, MC_CamFile, filepath) |
grabber.runScript(filepath) |
- | grabber.runScript(script) |
McSetParamInt(H, id, value) or McSetParamNmInt(H, name, value) | grabber.setInteger<M>(name, value) |
McSetParamFloat(H, id, value) or McSetParamNmFloat(H, name, value) | grabber.setFloat<M>(name, value) |
McSetParamStr(H, id, value) or McSetParamNmStr(H, name, value) | grabber.setString<M>(name, value) |
where H is a MC_HANDLE (the global MC_CONFIGURATION handle, a board handle, or a channel handle), and M specifies the target module (either SystemModule, InterfaceModule, DeviceModule, or StreamModule).
Camera configuration
MultiCam | eGrabber |
---|---|
- | grabber.runScript(filepath) |
- | grabber.runScript(script) |
- | grabber.setInteger<RemoteModule>(name, value), grabber.setFloat<RemoteModule>(name, value), or grabber.setString<RemoteModule>(name, value) |
Script files
MultiCam:
; CAM file
ChannelParam1 = Value1;
ChannelParam2 = Value2;
eGrabber:
// Euresys GenApi Script
var grabber = grabbers[0];
grabber.DevicePort.set('DeviceFeature1', Value1);
grabber.DevicePort.set('DeviceFeature2', Value2);
grabber.RemotePort.set('CameraFeatureA', ValueA);
Acquisition start/stop
MultiCam:
// start "live"
McSetParamInt(channel, MC_GrabCount, MC_INFINITE);
McSetParamInt(channel, MC_ChannelState, MC_ChannelState_ACTIVE);
// stop
McSetParamInt(channel, MC_ChannelState, MC_ChannelState_IDLE);
// grab 10 images
McSetParamInt(channel, MC_GrabCount, 10);
McSetParamInt(channel, MC_ChannelState, MC_ChannelState_ACTIVE);
eGrabber:
// start "live"
grabber.start();
// stop
grabber.stop();
// grab 10 images
grabber.start(10);
Synchronous (blocking) buffer reception
MultiCam:
MCSTATUS status;
MCSIGNALINFO info;
// wait for a surface
status = McWaitSignal(channel, MC_SIG_SURFACE_PROCESSING, timeout, &info);
if (status != MC_OK) {
...
}
MCHANDLE surface = info.SignalInfo;
// process surface
...
// make surface available for new images
status = McSetParamInt(surface, MC_SurfaceState, MC_SurfaceState_FREE);
if (status != MC_OK) {
...
}
eGrabber:
// wait for a buffer
Buffer buffer = grabber.pop(timeout);
// process buffer
...
// make buffer available for new images
buffer.push(grabber);
eGrabber:
{
// wait for a buffer
ScopedBuffer buffer(grabber, timeout);
// process buffer
...
// ScopedBuffer destructor takes care of making buffer available for new images
}
Callbacks
MultiCam:
class MyChannel {
public:
MyChannel() {
// create and configure channel
...
// enable "SURFACE_PROCESSING" events
status = McSetParamInt(channel, MC_SignalEnable + MC_SIG_SURFACE_PROCESSING,
MC_SignalEnable_ON);
if (status != MC_OK) {
...
}
// enable "END_EXPOSURE" events
status = McSetParamInt(channel, MC_SignalEnable + MC_SIG_END_EXPOSURE,
MC_SignalEnable_ON);
if (status != MC_OK) {
...
}
// register "extern C" callback function
MCSTATUS status = McRegisterCallback(channel, GlobalCallbackFunction, this);
if (status != MC_OK) {
...
}
}
void onEvent(MCSIGNALINFO *info) {
switch (info->Signal) {
case MC_SIG_SURFACE_PROCESSING:
MCHANDLE surface = info.SignalInfo;
// process surface
...
break;
case MC_SIG_END_EXPOSURE:
// handle "END_EXPOSURE" event
...
break;
}
}
private:
MCHANDLE channel;
};
void MCAPI GlobalCallbackFunction(MCSIGNALINFO *info) {
if (info && info->Context) {
MyGrabber *grabber = (MyGrabber *)info->Context;
grabber->onEvent(info);
}
};
eGrabber:
class MyGrabber : public EGrabber<CallbackSingleThread> {
public:
MyGrabber(EGenTL &gentl) : EGrabber<CallbackSingleThread>(gentl) {
// configure grabber
...
// enable "NewBuffer" events
enableEvent<NewBufferData>();
// enable "Cic" events
enableEvent<CicData>();
}
private:
virtual void onNewBufferEvent(const NewBufferData& data) {
ScopedBuffer buffer(*this, data);
// process buffer
...
}
virtual void onCicEvent(const CicData &data) {
// handle "Cic" event
...
}
};
Synchronous (blocking) event handling
MultiCam:
class MyChannel {
public:
MyChannel() {
// create and configure channel
...
// enable "END_EXPOSURE" events
status = McSetParamInt(channel, MC_SignalEnable + MC_SIG_END_EXPOSURE,
MC_SignalEnable_ON);
if (status != MC_OK) {
...
}
}
void waitForEvent(uint32_t timeout) {
// wait for an event
MCSTATUS status = McWaitSignal(channel, MC_SIG_END_EXPOSURE, timeout, &info);
if (status != MC_OK) {
...
}
// handle "END_EXPOSURE" event
...
}
private:
...
};
eGrabber:
class MyGrabber : public EGrabber<CallbackOnDemand> {
public:
MyGrabber(EGenTL &gentl) : EGrabber<CallbackOnDemand>(gentl) {
// configure grabber
...
// enable "Cic" events
enableEvent<CicData>();
}
void waitForEvent(uint64_t timeout) {
// wait for an event
processEvent<CicData>(timeout);
}
private:
// onCicEvent is called by processEvent when a "Cic" event occurs
virtual void onCicEvent(const CicData &data) {
// handle "Cic" event
...
}
};