coaxpress/resource/framegrabber/downloads/Vision Point/Documentation/Samples/KYFGLibGenTL_SimpleTest/GenTLCheck.cpp

761 lines
20 KiB
C++
Raw Normal View History

// GenTLCheck.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#define SIZE_WIDTH 1920
#define SIZE_HEIGHT 1080
#define CAMERA_XML_ACQUISITION_START_REG 0x1005C
#define CAMERA_XML_ACQUISITION_STOP_REG 0x1005C
#define BUFFER_AMOUNT 16
#define STREAM_CALLBACK_COUNT 0 // 0- infinate
// #define BLOCK_STREAM
#ifdef _WIN32
#include "windows.h"
#include <conio.h>
#else
#define MAX_PATH 256
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <string.h>
#include <iostream>
#include <iomanip>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <thread>
#include <unistd.h>
#define Sleep(ms) usleep(ms * 1000)
int _kbhit (void)
{
struct timeval tv;
fd_set rdfs;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rdfs);
FD_SET (STDIN_FILENO, &rdfs);
select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &rdfs);
}
#endif
#include "GenTL_v1_5.h"
#include "hwcti.h"
#include "ky_os.h"
ky_lib hcti = NULL;
tl_calls tl;
using namespace GenTL;
#define MAX_INTERFACES 8
struct EventDataStruct
{
DS_HANDLE m_hStream;
EVENT_HANDLE m_Hevent;
};
TL_HANDLE hTL = nullptr;
uint32_t interfaceIndex = 0;
struct InterfaceInfo
{
// Inderface device
IF_HANDLE hIface = GENTL_INVALID_HANDLE;
DEV_HANDLE hDev = GENTL_INVALID_HANDLE;
// Camera port
PORT_HANDLE hDevice = GENTL_INVALID_HANDLE;
// Stream
DS_HANDLE hStream = GENTL_INVALID_HANDLE;
// Event
EVENT_HANDLE hEvent = GENTL_INVALID_HANDLE; // new buffer event
std::thread eventThread;
EventDataStruct eventDataStruct;
// Buffers
BUFFER_HANDLE buffHandleArr[BUFFER_AMOUNT] = { GENTL_INVALID_HANDLE };
unsigned char* buffArrPtr[BUFFER_AMOUNT] = { 0 };
};
InterfaceInfo g_intefaceInfo;
void PrintHelp(void)
{
printf("\n\r=============================================\n\r"
"? - help\n\r"
"[0-7]-select and open interface\n\r"
"l - close interface\n\r"
#ifndef BLOCK_STREAM
"s - start\n\r"
"t - stop\n\r"
"k - test event kill\n\r"
#endif
"r <address> - read camera register\n\r"
"w <address> <value> - write camera register\n\r"
"x - extract camera xml file\n\r"
"g - extract grabber xml file\n\r"
"e - exit\n\r"
"=============================================\n\r"
);
}
bool InitLib( void )
{
#ifdef _WIN32
static const char* szKayaLibFolderEnv = "KAYA_VISION_POINT_BIN_PATH";
static const char chPatSep = '\\';
static const std::string sKayaLibCtiFile = "KYFGLibGenTL_vc141.cti";
#elif defined(__linux__)
static const char* szKayaLibFolderEnv = "KAYA_VISION_POINT_LIB_PATH";
static const char chPatSep = '/';
static const std::string sKayaLibCtiFile = "libKYFGLibGenTL.cti";
#endif
char* kayaLibEnv = getenv(szKayaLibFolderEnv);
std::string sKayaLibEnv(kayaLibEnv);
std::string cti = sKayaLibEnv + chPatSep + sKayaLibCtiFile;
ky_load_lib(cti.c_str(), hcti);
if (!hcti)
{
printf("The cti file %s failed to load\n\r", cti.c_str());
getchar();
return false;
}
LOAD_SYMBOLS(tl, hcti);
// Initiate GenTL library
tl.GCInitLib();
return true;
}
//3.8.3 OpenTL
//Retrieve TL Handle
TL_HANDLE OpenTL( void )
{
tl.TLOpen( &hTL );
return hTL;
}
//3.8.4 OpenInterface
//Retrieve first Interface Handle
IF_HANDLE OpenInterface(TL_HANDLE hTL )
{
bool8_t changed;
uint32_t NumInterfaces = 0;
char IfaceID[20];
size_t bufferSize = MAX_PATH;
IF_HANDLE hNewIface;
INFO_DATATYPE piType;
char buffer[MAX_PATH];
tl.TLGetInfo(hTL,TL_INFO_PATHNAME, &piType, buffer, &bufferSize);
// printf("dll path: %s\n", buffer);
bufferSize = 20;
tl.TLUpdateInterfaceList( hTL , &changed, 0);
tl.TLGetNumInterfaces( hTL, &NumInterfaces );
if ( NumInterfaces > interfaceIndex)
{
// Get inteface id string
tl.TLGetInterfaceID( hTL, interfaceIndex, IfaceID, &bufferSize );
// Open interface with index 0
tl.TLOpenInterface( hTL, IfaceID, &hNewIface );
/*bufferSize = MAX_PATH;
tl.GCGetPortInfo(hNewIface,PORT_INFO_MODULE, &piType, buffer, &bufferSize);
printf("module name: %s\n", buffer);*/
return hNewIface;
}
else
{
return GENTL_INVALID_HANDLE;
}
}
//3.8.5 OpenFirstDevice
//Retrieve first Device Handle
PORT_HANDLE OpenFirstDevice( IF_HANDLE hIF )
{
bool8_t changed;
uint32_t NumDevices = 0;
char DeviceID[20];
size_t bufferSize = 20;
DEV_HANDLE hNewDevice;
//PORT_HANDLE phRemoteDevice;
tl.IFUpdateDeviceList( hIF , &changed, 0 );
tl.IFGetNumDevices( hIF, &NumDevices );
if ( NumDevices > 0 )
{
// First query the buffer size
tl.IFGetDeviceID( hIF, 0, DeviceID, &bufferSize );
long result = 0;
INFO_DATATYPE piType;
size_t pSize = 20;
tl.IFGetDeviceInfo( hIF, DeviceID, DEVICE_INFO_ACCESS_STATUS, &piType, &result , &pSize);
// Open interface with index 0
tl.IFOpenDevice( hIF, DeviceID, DEVICE_ACCESS_CONTROL , &hNewDevice );
return hNewDevice;
}
else
{
return GENTL_INVALID_HANDLE;
}
}
//3.8.6 OpenFirstDataStream
//Retrieve first data Stream
DS_HANDLE OpenFirstDataStream( DEV_HANDLE hDev )
{
uint32_t NumStreams = 0;
char StreamID[20];
size_t buffersize = 20;
DS_HANDLE hNewStream;
GC_ERROR errorResult;
// Retrieve the number of Data Stream
tl.DevGetNumDataStreams( hDev, &NumStreams );
if ( NumStreams > 0 )
{
// Get ID of first stream using
errorResult = tl.DevGetDataStreamID( hDev, 0, StreamID, &buffersize );
// Instantiate Data Stream
errorResult = tl.DevOpenDataStream( hDev, StreamID, &hNewStream );
return hNewStream;
}
else
{
return GENTL_INVALID_HANDLE;
}
}
void OpenDataBuffer(InterfaceInfo* pInterfaceInfo)
{
size_t dataStreamPayloadSize = 0;
size_t iSize = sizeof(dataStreamPayloadSize);
INFO_DATATYPE iType;
tl.DSGetInfo(pInterfaceInfo->hStream, STREAM_INFO_PAYLOAD_SIZE, &iType, &dataStreamPayloadSize, &iSize );
for(size_t i = 0 ; i < BUFFER_AMOUNT; ++i)
{
pInterfaceInfo->buffArrPtr[i] = (unsigned char*)_aligned_malloc(dataStreamPayloadSize, 4096);
tl.DSAnnounceBuffer(pInterfaceInfo->hStream, pInterfaceInfo->buffArrPtr[i], dataStreamPayloadSize, nullptr, &pInterfaceInfo->buffHandleArr[i]);
}
}
void CloseDataBuffer(InterfaceInfo* pInterfaceInfo)
{
if (!pInterfaceInfo->hStream)
{
return;
}
for (size_t i = 0; i < BUFFER_AMOUNT; ++i)
{
if (pInterfaceInfo->buffArrPtr[i])
{
_aligned_free(pInterfaceInfo->buffArrPtr[i]);
pInterfaceInfo->buffArrPtr[i] = nullptr;
pInterfaceInfo->buffHandleArr[i] = GENTL_INVALID_HANDLE;
}
}
}
EVENT_HANDLE OpenBufferEvent(DS_HANDLE hStream)
{
EVENT_HANDLE eventHand;
tl.GCRegisterEvent(hStream, EVENT_NEW_BUFFER, &eventHand);
//DSStartAcquisition(hStream, 0, GENTL_INFINITE);
return eventHand;
}
void CloseBufferEvent(DS_HANDLE hStream)
{
tl.GCUnregisterEvent(hStream, EVENT_NEW_BUFFER);
}
void CloseDataStream (DS_HANDLE hStream )
{
if (GENTL_INVALID_HANDLE == hStream)
{
return;
}
tl.DSClose( hStream );
}
void CloseDevice(DEV_HANDLE hDevice )
{
if (GENTL_INVALID_HANDLE == hDevice)
{
return;
}
tl.DevClose( hDevice );
}
void CloseInterface(IF_HANDLE hIface )
{
if (GENTL_INVALID_HANDLE == hIface)
{
return;
}
tl.IFClose( hIface );
}
void CloseTL(TL_HANDLE hTL )
{
if (GENTL_INVALID_HANDLE == hTL)
{
return;
}
tl.TLClose( hTL );
}
void CloseLib( void )
{
tl.GCCloseLib( );
}
int32_t ReadGenTLValue(PORT_HANDLE hDev, uint64_t address, uint32_t* value)
{
size_t size = sizeof(uint32_t);
*value = 0;
GC_ERROR err = tl.GCReadPort(hDev, address, value, &size);
return err;
}
int32_t WriteGenTLValue(PORT_HANDLE hDev, uint64_t address, uint32_t value)
{
size_t size = sizeof(uint32_t);
GC_ERROR err = tl.GCWritePort(hDev, address, &value, &size);
return err;
}
void splitString(const std::string &s, const char delim, std::vector<std::string> &elems)
{
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim))
{
elems.push_back(item);
}
}
void Test_XML(PORT_HANDLE hDev)
{
const uint32_t MAX_CAM_XML_STRING_LENGTH = 256;
const uint32_t DEVICE_XMLURL_REG = 0x00000018;
size_t size = 4;
size_t size2 = 4;
uint32_t maxStrLength = MAX_CAM_XML_STRING_LENGTH;
char xmlAddrString[MAX_CAM_XML_STRING_LENGTH] = {0};
char xmlAddrString2[MAX_CAM_XML_STRING_LENGTH] = {0};
size = MAX_CAM_XML_STRING_LENGTH;
GC_ERROR err = tl.GCGetPortURL(hDev, xmlAddrString, &size);
// size2 = MAX_CAM_XML_STRING_LENGTH;
// INFO_DATATYPE iType;
// GC_ERROR err2 = tl.GCGetPortURLInfo(hDev, 0, URL_INFO_URL, &iType, xmlAddrString2, &size2);
if(err != GC_ERR_SUCCESS)
{
printf("Cann't read URL\n");
return;
}
else
{
printf("URL: %s\n", xmlAddrString);
}
std::string xmlUrl(xmlAddrString);
std::vector<std::string> xmlUrlSplit;
splitString(xmlUrl, ';', xmlUrlSplit);
uint64_t xmlFileSize = 0, xmlFileLocation = 0;
sscanf_s(xmlUrlSplit.at(1).c_str(), "%llx", &xmlFileLocation); // read xml file address
sscanf_s(xmlUrlSplit.at(2).c_str(), "%llx", &xmlFileSize); // read xml file size
static const char* xmlExtXml = ".xml";
static const char* xmlExtZip = ".zip";
#ifdef _WIN32
static const char* sXmlOutputFilePath = "C:/Temp/GenTLTestXML";
#elif defined(__linux__)
static const char* sXmlOutputFilePath = "/tmp/GenTLTestXML";
#endif
std::string xmlOutFileName(sXmlOutputFilePath);
if (std::string::npos != xmlUrlSplit.at(0).find(xmlExtXml))
{
xmlOutFileName += std::string(xmlExtXml);
}
else if(std::string::npos != xmlUrlSplit.at(0).find(xmlExtZip))
{
xmlOutFileName += std::string(xmlExtZip);
}
else
{
printf("Failed to find xml file extension\n\r");
return;
}
char* xmlString = new char[xmlFileSize + 1];
GC_ERROR err3 = tl.GCReadPort(hDev, xmlFileLocation, xmlString, &xmlFileSize);
FILE* outFile = NULL;
outFile = fopen(xmlOutFileName.c_str(), "wb");
if (outFile) // write to file only if it was opened
{
fwrite(xmlString, 1, xmlFileSize, outFile);
fclose(outFile);
}
delete [] xmlString;
}
void Test_EventKill(EVENT_HANDLE eventHandle)
{
tl.EventKill(eventHandle);
}
unsigned int event_thread_impl(void * pData)
{
EventDataStruct* eventDataStruct = (EventDataStruct*)pData;
EVENT_HANDLE eHandle = eventDataStruct->m_Hevent;
uint8_t buffer[100];
size_t bufferSize = sizeof(buffer);
int counter = STREAM_CALLBACK_COUNT;
GC_ERROR error;
do {
error = tl.EventGetData(eHandle, buffer, &bufferSize, GENTL_INFINITE);
BUFFER_HANDLE bufferHandle = ((EVENT_NEW_BUFFER_DATA*)buffer)->BufferHandle;
printf("Event ended for buffer 0x%p with error=%d\n\r", bufferHandle, error);
tl.DSQueueBuffer(eventDataStruct->m_hStream, bufferHandle);
} while (
(error == GC_ERR_SUCCESS)
&&
#if (0==STREAM_CALLBACK_COUNT)
(1)
#else
(--counter > 0)
#endif
);
return 0;
}
void Test_AcquisitionStart(InterfaceInfo* pInterfaceInfo)
{
if (pInterfaceInfo->hStream != GENTL_INVALID_HANDLE)
{
// data stream already allocated, first delete data stream
return;
}
// create data stream
pInterfaceInfo->hStream = OpenFirstDataStream(pInterfaceInfo->hDev);
// allocated stream buffers
OpenDataBuffer(pInterfaceInfo);
// create stream event and thread
pInterfaceInfo->hEvent = OpenBufferEvent(pInterfaceInfo->hStream);
pInterfaceInfo->eventDataStruct.m_Hevent = pInterfaceInfo->hEvent;
pInterfaceInfo->eventDataStruct.m_hStream = pInterfaceInfo->hStream;
pInterfaceInfo->eventThread = std::thread(event_thread_impl, &pInterfaceInfo->eventDataStruct);
tl.DSFlushQueue(pInterfaceInfo->hStream, ACQ_QUEUE_ALL_TO_INPUT);
tl.DSStartAcquisition(pInterfaceInfo->hStream, 0, GENTL_INFINITE);
// send "AcquisitionStart" to camera
const uint32_t startAcquisitionReg = 1;
size_t startAcquisitionRegSize = sizeof(startAcquisitionReg);
const uint64_t startAcquisitionRegAddr = CAMERA_XML_ACQUISITION_START_REG;
tl.GCWritePort(pInterfaceInfo->hDevice, startAcquisitionRegAddr, &startAcquisitionReg, &startAcquisitionRegSize); // start acquisition
}
void Test_AcquisitionStop(InterfaceInfo* pInterfaceInfo)
{
if (pInterfaceInfo->hStream == GENTL_INVALID_HANDLE)
{
// No data stream available
return;
}
// send "AcquisitionStop" to camera
const uint32_t stopAcquisitionReg = 0;
size_t stopAcquisitionRegSize = sizeof(stopAcquisitionReg);
const uint64_t stopAcquisitionRegAddr = CAMERA_XML_ACQUISITION_STOP_REG;
tl.GCWritePort(pInterfaceInfo->hDevice, stopAcquisitionRegAddr, &stopAcquisitionReg, &stopAcquisitionRegSize); // stop acquisition
tl.DSStopAcquisition(pInterfaceInfo->hStream, 0);
// tl.GCUnregisterEvent(newEvent, 1);
tl.DSFlushQueue(pInterfaceInfo->hStream, ACQ_QUEUE_ALL_DISCARD);
CloseBufferEvent(pInterfaceInfo->hStream);
pInterfaceInfo->hEvent = GENTL_INVALID_HANDLE;
// wait for eventThread to terminate
std::cout << "eventThread's id: " << pInterfaceInfo->eventThread.get_id() << '\n';
if (pInterfaceInfo->eventThread.joinable())
{
pInterfaceInfo->eventThread.join();
}
CloseDataBuffer(pInterfaceInfo);
CloseDataStream(pInterfaceInfo->hStream);
pInterfaceInfo->hStream = GENTL_INVALID_HANDLE;
}
struct ResourceReleaser
{
ResourceReleaser(InterfaceInfo* pInterfaceInfo)
: m_interfaceInfo(pInterfaceInfo)
{
}
~ResourceReleaser()
{
ReleaseInterface();
CloseTL(hTL);
hTL = GENTL_INVALID_HANDLE;
CloseLib();
ky_free_lib(hcti);
}
void ReleaseInterface()
{
Test_AcquisitionStop(m_interfaceInfo);
CloseDevice(m_interfaceInfo->hDevice);
m_interfaceInfo->hDevice = GENTL_INVALID_HANDLE;
CloseInterface(m_interfaceInfo->hIface);
m_interfaceInfo->hIface = GENTL_INVALID_HANDLE;
}
InterfaceInfo* m_interfaceInfo;
}; // struct ResourceReleaser
struct OpenScopeQuard
{
OpenScopeQuard(ResourceReleaser& handlesReleaser)
: m_refHandlesReleaser(handlesReleaser)
, m_ScopeSucceeded(false)
{ }
~OpenScopeQuard()
{
if (!m_ScopeSucceeded)
{
m_refHandlesReleaser.ReleaseInterface();
}
}
ResourceReleaser& m_refHandlesReleaser;
bool m_ScopeSucceeded;
};
int main(int argc, char* argv[])
{
GC_ERROR ret_code;
char choice = 0;
// Automatically release resources when this scope exits:
ResourceReleaser resourceReleaser(&g_intefaceInfo);
if (!InitLib())
{
return -1;
}
hTL = OpenTL();
PrintHelp();
while(choice != 'e')
{
Sleep(1);
if(_kbhit())
{
choice=getchar();
printf("\nGenTL>%c\n", choice);
if (choice >= '0' && choice <= '7') // Open selected interface
{
resourceReleaser.ReleaseInterface(); // release old interface
OpenScopeQuard openScopeQuard(resourceReleaser);
interfaceIndex = choice - '0';
printf("Openning interface #%d\n", interfaceIndex);
g_intefaceInfo.hIface = OpenInterface(hTL);
if (!g_intefaceInfo.hIface)
{
printf("Failed to find Frame Grabber\n");
getchar();
continue;
}
printf("Successfully found Frame Grabber\n");
g_intefaceInfo.hDev = OpenFirstDevice(g_intefaceInfo.hIface);
if (!g_intefaceInfo.hDev)
{
printf("Failed to find remote device\n");
getchar();
continue;
}
tl.DevGetPort(g_intefaceInfo.hDev, &g_intefaceInfo.hDevice);
if (!g_intefaceInfo.hDevice)
{
printf("Failed to find Camera\n");
getchar();
continue;
}
printf("Successfully found Camera\n");
openScopeQuard.m_ScopeSucceeded = true;
}//if (choice >= '0' && choice <= '7')
else
switch (choice)
{
case '?':
PrintHelp();
break;
case 'l': // Close interface
resourceReleaser.ReleaseInterface();
break;
case 'g': // Test_XML(hIface) (grabber)
Test_XML(g_intefaceInfo.hIface);
break;
case 'x': // Test_XML(hDevice) (camera)
Test_XML(g_intefaceInfo.hDevice);
break;
case 'r': // ReadGenTLValue
{
uint64_t address = 0;
uint32_t value = 0;
size_t size = 0;
printf("Address(hex): ");
std::cin >> std::hex >> address;
ret_code = ReadGenTLValue(g_intefaceInfo.hDevice, address, &value);
if (ret_code == GC_ERR_SUCCESS)
{
printf("Successfully reg read value(dec) = %d\n", value);
}
else
{
printf("Reg read error = %d\n", ret_code);
}
break;
}
case 'w': // WriteGenTLValue
{
uint64_t address = 0;
uint32_t value = 0;
size_t size = 0;
printf("Address(hex): ");
std::cin >> std::hex >> address;
printf("value(dec): ");
std::cin >> std::dec >> value;
ret_code = WriteGenTLValue(g_intefaceInfo.hDevice, address, value);
if (ret_code == GC_ERR_SUCCESS)
{
printf("Successfully reg write value(dec) = %d\n", value);
}
else
{
printf("Reg write error = %d\n", ret_code);
}
break;
}
#ifndef BLOCK_STREAM
case 'k': // Test_EventKill
Test_EventKill(g_intefaceInfo.hEvent);
break;
case 't': // "AcquisitionStop"
{
Test_AcquisitionStop(&g_intefaceInfo);
break;
}
case 's': // "AcquisitionStart"
{
Test_AcquisitionStart(&g_intefaceInfo);
break;
}
#endif
default:
break;
}//switch (choice)
}//if(_kbhit())
}//while(choice != 'e')
// resourceReleaser will release all opened handles upon exiting
return 0;
}