MultiCamユーザー向けeGrabber
概念
MultiCam | eGrabber |
---|---|
ボード | インターフェース |
チャンネル | デバイス + データストリーム |
サーフェス | バッファー |
サーフェスクラスター(MC_Cluster) | データストリームに自らの情報を設定したバッファー |
- | リモートデバイス(カメラ) |
MultiCamパラメーター | GenApi set/get機能 |
- | GenApiコマンド |
CAMファイル | Euresys GenApiスクリプト |
- | CallbackOnDemand |
コールバック関数 | CallbackSingleThread |
- | CallbackMultiThread |
初期化
MultiCam:
MCSTATUS status = McOpenDriver(NULL);
if (status != MC_OK) {
...
}
eGrabber:
Euresys::EGenTL gentl;
チャンネルの作成
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);
サーフェスの作成(自動)
MultiCam:
status = McSetParamInt(channel, MC_SurfaceCount, BUFFER_COUNT);
if (status != MC_OK) {
...
}
eGrabber:
grabber.reallocBuffers(BUFFER_COUNT);
サーフェスの作成(手動)
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]));
}
サーフェスクラスターのリセット
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();
フレームグラバーの設定
MultiCam | eGrabber |
---|---|
McSetParamStr(H, MC_CamFile, filepath) | grabber.runScript(filepath) |
- | grabber.runScript(script) |
McSetParamInt(H, id, value)またはMcSetParamNmInt(H, name, value) | grabber.setInteger<M>(name, value) |
McSetParamFloat(H, id, value)またはMcSetParamNmFloat(H, name, value) | grabber.setFloat<M>(name, value) |
McSetParamStr(H, id, value)またはMcSetParamNmStr(H, name, value) | grabber.setString<M>(name, value) |
HはMC_HANDLE(グローバルMC_CONFIGURATIONハンドル、ボードハンドル、またはチャンネルハンドル)で、Mはターゲットモジュールを示します(SystemModule、InterfaceModule、DeviceModule、またはStreamModule)。
カメラの設定
MultiCam | eGrabber |
---|---|
- | grabber.runScript(filepath) |
- | grabber.runScript(script) |
- | grabber.setInteger<RemoteModule>(name, value)、grabber.setFloat<RemoteModule>(name, value)、またはgrabber.setString<RemoteModule>(name, value) |
スクリプトファイル
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);
取得の開始と停止
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);
同期(ブロッキング)バッファー受信
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
}
コールバック
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
...
}
};
同期(ブロッキング)イベント処理
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
...
}
};