GigE Vision Events

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: 2
  • Reconnect: 3
  • LinkLoss: 1000
  • CCPLoss: 1001
  • DevEvent: 1003
  • Test: 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.

2 Likes