The second way, if the camera’s GenApi node map does not support it, is the :cvb: INotify
interface:
First we create this harness:
IMG hCamera = NULL;
if(const char *cvbDir = getenv("CVB"))
{
char genicamPath[_MAX_PATH] = { 0 };
snprintf(genicamPath, _MAX_PATH, "%sDrivers\\GenICam.vin", cvbDir);
hCamera = OpenDriverPort(genicamPath, 0);
}
// here we will put the code from below
ReleaseObject(hCamera);
Using OpenDriverPort
from here:
https://forum.commonvisionblox.com/t/old-image-broken-after-setting-new-camport/66/5?u=parsd
This code simply opens the first available configured camera and frees it.
If I call this function in the section marked by the comment above:
void ListINotifyEvents(IMG hCamera)
{
assert(CanNotify(hCamera));
size_t numEvents = 0;
NOGetNumSupported(hCamera, numEvents);
for(size_t eventIndex = 0; eventIndex < numEvents; ++eventIndex)
{
char descriptionBuffer[128] = { 0 }; // this should suffice
size_t desciptionBufferSize = sizeof(descriptionBuffer);
CVNotifyEvent_t eventId = -1;
NOGetDescription(hCamera, eventIndex, descriptionBuffer, desciptionBufferSize, eventId);
printf("- %s: %i\n", descriptionBuffer, eventId);
}
}
I get the following output (:cvb: 2017/13.00.00x):
Disconnect
: 2Reconnect
: 3LinkLoss
: 1000CCPLoss
: 1001DevEvent
: 1003Test
: 10000
What we want here is the DevEvent
(device event) which then is the GEV event in our case. We also need a callback function:
void __stdcall CameraEvent(CVNotifyEvent_t eventID, void *pBuffer, size_t bufferSize, CVNotifyDatatype_t bufferDataType, void *pPrivate);
which we then register:
intptr_t cameraEventToken = -1;
cvbres_t result = NORegister(hCamera, 1003, &CameraEvent, NULL, cameraEventToken);
if(result < 0)
; // error handling
The data delivered via CameraEvent
is transport technology dependent. In case of a GigE Vision event data, the event ID can be found in the second WORD
:
void __stdcall CameraEvent(CVNotifyEvent_t eventID, void *pBuffer, size_t bufferSize, CVNotifyDatatype_t bufferDataType, void *pPrivate)
{
assert(bufferSize >= 4);
const uint16_t *pWords = reinterpret_cast<const uint16_t *>(pBuffer);
uint16_t eventId = pWords[1];
// ...
}
So, this is how you can get the event id via INotify
. I find this a) more complicated and b) it is transport technology dependent. Thus if you have a U3V device, the pBuffer
interpretation is different.