#include <stdio.h>
#include <stdlib.h>
#include "ItalaApiC/ItalaC.h"
#ifdef _WIN32
#include <windows.h>
#define SLEEP_MS(ms) Sleep(ms)
#else
#include <unistd.h>
#define SLEEP_MS(ms) usleep(ms * 1000)
#endif
#define SLEEP 1000
ItalaError ErrorManager(ItalaError e) {
size_t sizeMessage = 255;
char* message = (char*)malloc(sizeof(char) * sizeMessage);
ERR_GetLastErrorMessage(message, &sizeMessage);
printf("\nITALA ERROR (%d):\t%s, %zu char", ERR_GetLastErrorCode(), message, sizeMessage);
free(message);
return e;
}
// Define a callback function which can be registered to a node with GenApi.
// When the target node value changes, the callback is executed. The value
// change is performed automatically by Itala API when the event related
// to the node occurs (e.g. when an exposure end event occurs,
// the EventExposureEndTimestamp node value changes).
void EventExposureEndTimestampCallback(H_NODE hNode, void* pContext) {
ItalaError error = ItalaErrorSuccess;
int64_t timestamp = 0;
error = NODE_IntegerGetValue(hNode, ×tamp);
if (!error)
printf(
"\tExposureEndEventTimestamp value change detected by the node callback, new value is "
"%jd\n",
timestamp);
else
printf("\tSome erros occures in the callback.\n");
}
// Define a callback which is automatically called when a device event is detected.
void DeviceEventCallback(H_DEVICE hDevice, uint64_t eventId, void* pContext) {
H_NODEMAP hNodeMap = NULL;
DEV_GetNodeMap(hDevice, &hNodeMap);
H_NODE hNodeEventExposureEnd = NULL;
NODEMAP_GetNode(hNodeMap, "EventExposureEnd", &hNodeEventExposureEnd);
int64_t eventExposureEndValue = 0;
NODE_IntegerGetValue(hNodeEventExposureEnd, &eventExposureEndValue);
if (eventExposureEndValue == eventId) {
H_NODE hNodeEventExposereEndTimestamp = NULL;
NODEMAP_GetNode(hNodeMap, "EventExposureEndTimestamp", &hNodeEventExposereEndTimestamp);
int64_t eventExposereEndTimestampValue = 0;
NODE_IntegerGetValue(hNodeEventExposereEndTimestamp, &eventExposereEndTimestampValue);
printf("\nEvent callback called on device event, occurred at %jd\n\n",
eventExposereEndTimestampValue);
}
}
int main(int argc, char** argv) {
printf("***** Events example started. *****\n");
ItalaError error = ItalaErrorSuccess;
error = SYS_Initialize();
if (error) return ErrorManager(error);
size_t devicesInfoSize = 0;
error = SYS_EnumerateDevices(700);
if (error) return ErrorManager(error);
error = SYS_GetDeviceCount(&devicesInfoSize);
if (error) return ErrorManager(error);
if (devicesInfoSize == 0) {
printf("No devices found. Example canceled.\n");
return ItalaErrorError;
}
DeviceInfo deviceInfo;
error = SYS_GetDeviceByIndex(0, &deviceInfo);
if (error) return ErrorManager(error);
if (deviceInfo.AccessStatus != AvailableReadWrite) {
printf("Target device is unaccessible in RW mode. Example canceled.\n");
return ItalaErrorError;
}
H_DEVICE hDevice = NULL;
error = SYS_CreateDevice(deviceInfo, &hDevice);
if (error) return ErrorManager(error);
printf("First device found is initialized.\n");
H_NODEMAP hNodeMap = NULL;
error = DEV_GetNodeMap(hDevice, &hNodeMap);
if (error) return ErrorManager(error);
// Select the exposure end event..
H_NODE hNodeEventSelector = NULL;
error = NODEMAP_GetNode(hNodeMap, "EventSelector", &hNodeEventSelector);
if (error) return ErrorManager(error);
bool isWritable = false;
error = IsNodeWritable(hNodeEventSelector, &isWritable);
if (error) return ErrorManager(error);
if (!isWritable) {
printf("Unable to select the exposure end event. Aborting.\n");
return ItalaErrorError;
}
error = NODE_FromString(hNodeEventSelector, "ExposureEnd");
// ..and enable it on the device. The original value is also kept so
// that it can be restored at the end of the example.
H_NODE hNodeEventNotification = NULL;
error = NODEMAP_GetNode(hNodeMap, "EventNotification", &hNodeEventNotification);
if (error) return ErrorManager(error);
isWritable = false;
error = IsNodeWritable(hNodeEventNotification, &isWritable);
if (error) return ErrorManager(error);
if (!isWritable) {
printf("Unable to turn on notifications for exposure end event. Aborting.\n");
return ItalaErrorError;
}
int64_t originalEventNotification = 0;
error = NODE_EnumerationGetIntValue(hNodeEventNotification, &originalEventNotification);
if (error) return ErrorManager(error);
error = NODE_FromString(hNodeEventNotification, "On");
if (error) return ErrorManager(error);
printf("Exposure end event enabled on the device.\n");
// Start to listen for events on the host.
error = DEV_EnableEvents(hDevice);
printf("Event listening enabled on the host.\n");
// Get one of the exposure end event related nodes. In this case, the frame timestamp
// is chosen. WARNING: the event node is not available until the event occurs, so no
// availability check is performed here.
H_NODE hNodeEventExposureEndTimestamp = NULL;
NODEMAP_GetNode(hNodeMap, "EventExposureEndTimestamp", &hNodeEventExposureEndTimestamp);
if (error) return ErrorManager(error);
// The callback is registered to the EventExposureEndTimestamp node. Every time the
// node value changes, the function gets called and the new value can be read.
H_NODECALLBACK hNodeCallback = NULL;
error = NODE_RegisterCallback(hNodeEventExposureEndTimestamp, EventExposureEndTimestampCallback,
NULL, &hNodeCallback);
if (error) return ErrorManager(error);
printf("Callback registered to the EventExposureEndTimestamp node..\n");
// Alternatively, a user-defined callback is registered to ItalaApi.
// When a device event occurs, the callback registered by the user is called.
error = DEV_RegisterEventCallback(hDevice, DeviceEventCallback, NULL);
if (error) return ErrorManager(error);
error = DEV_StartAcquisition(hDevice);
if (error) return ErrorManager(error);
// Let the camera perform some exposures..
SLEEP_MS(SLEEP);
error = DEV_StopAcquisition(hDevice);
if (error) return ErrorManager(error);
// When the callback-on-event functionality is no longer required, the function
// must be unregistered from the node. The same is true for the device event callback.
// The event listening must be disabled.
error = NODE_DeregisterCallback(hNodeEventExposureEndTimestamp, hNodeCallback);
if (error) return ErrorManager(error);
error = DEV_DisableEvents(hDevice);
if (error) return ErrorManager(error);
error = DEV_DeregisterEventCallback(hDevice);
if (error) return ErrorManager(error);
// Set original value in camera
error = NODE_EnumerationSetIntValue(hNodeEventNotification, originalEventNotification);
if (error) return ErrorManager(error);
error = DEV_Dispose(hDevice);
hDevice = NULL;
if (error) return ErrorManager(error);
printf("Device instance disposed.\n");
error = SYS_Dispose();
if (error) return ErrorManager(error);
printf("System instance disposed.\n");
return 0;
}