lms-video/Gem/plugins/videoAVT/videoAVT.cpp
Santi Noreña e85d191b46 - Reestructuración de ficheros y directorios general
- merge v0.01 --> Añadido fileselector
- Añadidas fuentes de Gem y Pure Data
- pix2jpg incluído en Gem. Archivos de construcción de Gem modificados.
- Añadido fichero ompiling.txt con instrucciones de compilación
2013-02-04 18:00:17 +01:00

568 lines
14 KiB
C++

////////////////////////////////////////////////////////
//
// GEM - Graphics Environment for Multimedia
//
// zmoelnig@iem.kug.ac.at
//
// Implementation file
//
// Copyright (c) 2010-2011 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at
// For information on usage and redistribution, and for a DISCLAIMER OF ALL
// WARRANTIES, see the file, "LICENSE.txt"
//
/////////////////////////////////////////////////////////
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "videoAVT.h"
#include "plugins/PluginFactory.h"
#include <sstream>
#include <sys/types.h>
#ifdef _WIN32
# include <winsock.h>
#else
# include <sys/socket.h>
# include <netdb.h>
#endif
#include <errno.h>
using namespace gem::plugins;
#include "Gem/RTE.h"
#include "Gem/Exception.h"
#if 0
# define debug ::post
#else
# define debug
#endif
/////////////////////////////////////////////////////////
//
// videoAVT
//
/////////////////////////////////////////////////////////
// Constructor
//
/////////////////////////////////////////////////////////
#ifdef HAVE_AVT
#define MAX_CAMERA_LIST 20
REGISTER_VIDEOFACTORY("avt", videoAVT);
struct PvApiInitClass {
PvApiInitClass(void) {
unsigned long major=0, minor=0;
PvVersion(&major, &minor);
// post("Prosilica AVT SDK %d.%d", major, minor);
if(ePvErrResources==PvInitialize()) {
throw(GemException("unable to initialization PvAPI"));
}
}
virtual ~PvApiInitClass(void) {
PvUnInitialize();
}
};
videoAVT :: videoAVT() : videoBase("avt"),
m_grabber(NULL)
{
m_width=0;
m_height=0;
static PvApiInitClass paic;
int i=0;
for(i=0;i<AVT_FRAMESCOUNT;i++) {
m_frames[i].ImageBuffer = NULL;
m_frames[i].ImageBufferSize = 0;
}
provide("gige");
}
////////////////////////////////////////////////////////
// Destructor
//
/////////////////////////////////////////////////////////
videoAVT :: ~videoAVT()
{
close();
resizeFrames(0);
}
void videoAVT::resizeFrames(unsigned long int size) {
int i=0;
for(i=0;i<AVT_FRAMESCOUNT;i++) {
if(m_frames[i].ImageBuffer) {
unsigned char*frame=(unsigned char*)m_frames[i].ImageBuffer;
delete[]frame;
m_frames[i].ImageBuffer = NULL;
}
m_frames[i].ImageBufferSize = 0;
if(size) {
m_frames[i].ImageBuffer = new unsigned char[size];
if(m_frames[i].ImageBuffer)
m_frames[i].ImageBufferSize = size;
}
m_frames[0].AncillaryBuffer=NULL;
m_frames[0].AncillaryBufferSize=0;
}
}
////////////////////////////////////////////////////////
// frame grabber
//
/////////////////////////////////////////////////////////
bool videoAVT :: grabFrame() {
return true;
}
void videoAVT::grabbedFrame(const tPvFrame&pFrame) {
/* frame successfully grabbed -> convert it into a pixbuf */
bool success=true;
lock();
m_image.image.xsize=pFrame.Width;
m_image.image.ysize=pFrame.Height;
m_image.image.setCsizeByFormat(GL_RGBA);
m_image.image.reallocate();
switch(pFrame.Format) {
case(ePvFmtMono8) : m_image.image.fromGray((unsigned char *)pFrame.ImageBuffer);break;
// case(ePvFmtMono16): m_image.image.fromGray((unsigned short*)pFrame.ImageBuffer);break;
case(ePvFmtRgb24) : m_image.image.fromRGB ((unsigned char *)pFrame.ImageBuffer);break;
case(ePvFmtBgr24) : m_image.image.fromBGR ((unsigned char *)pFrame.ImageBuffer);break;
case(ePvFmtRgba32): m_image.image.fromRGBA((unsigned char *)pFrame.ImageBuffer);break;
case(ePvFmtBgra32): m_image.image.fromBGRA((unsigned char *)pFrame.ImageBuffer);break;
case(ePvFmtBayer8): case(ePvFmtBayer16): do {
unsigned char*data=m_image.image.data;
// PixelPadding is most likely plain wrong; need to test what it really means
PvUtilityColorInterpolate(&pFrame,
&data[chRed],
&data[chGreen],
&data[chBlue],
2, // PixelPadding (Alpha)
0 // LinePadding
);
} while(0);
break;
case (ePvFmtRgb48):
case(ePvFmtMono12Packed): case(ePvFmtBayer12Packed):
case (ePvFmtYuv411): case(ePvFmtYuv422): case(ePvFmtYuv444):
default:
// ouch
success=false;
}
if(success) {
m_image.image.upsidedown=true;
m_image.newimage=true;
}
unlock();
}
void videoAVT::grabCB(tPvFrame*pFrame) {
videoAVT*me=(videoAVT*)pFrame->Context[0];
if(me && ePvErrSuccess==pFrame->Status)
me->grabbedFrame(*pFrame);
// if the frame was completed we re-enqueue it
if(pFrame->Status != ePvErrUnplugged && pFrame->Status != ePvErrCancelled)
{
PvCaptureQueueFrame(me->m_grabber, pFrame, grabCB);
}
}
pixBlock* videoAVT::getFrame(void) {
if(!(m_haveVideo && m_capturing))return NULL;
lock();
return &m_image;
}
/////////////////////////////////////////////////////////
// openDevice
//
/////////////////////////////////////////////////////////
bool videoAVT :: openDevice(gem::Properties&props)
{
if(m_grabber)closeDevice();
unsigned long cameraNum=PvCameraCount();
tPvCameraInfo*cameraList=new tPvCameraInfo[cameraNum];
if(m_devicenum>=0) {
verbose(1, "AVT trying to open #%d of %d devices", m_devicenum, cameraNum);
if(cameraNum>m_devicenum && (cameraList[m_devicenum].PermittedAccess == ePvAccessMaster)) {
if (PvCameraOpen(cameraList[m_devicenum].UniqueId, ePvAccessMaster, &m_grabber) != ePvErrSuccess) {
m_grabber=NULL;
}
}
} else {
verbose(1, "AVT trying to open device '%s'", m_devicename.c_str());
/*
cameraList[i].SerialString,
cameraList[i].DisplayName,
cameraList[i].UniqueId,
IP
*/
unsigned long i=0;
errno=0;
const unsigned long uid=strtoul(m_devicename.c_str(), NULL, 0);
if(NULL==m_grabber && 0==errno) {
verbose(1, "checking UniqueID: 0x% 8x", uid);
for(i=0; i<cameraNum; i++) {
if(uid==cameraList[i].UniqueId && PvCameraOpen(cameraList[i].UniqueId, ePvAccessMaster, &m_grabber) == ePvErrSuccess) {
break;
}
}
}
if(NULL==m_grabber) {
verbose(1, "checking SerialString: %s", m_devicename.c_str());
for(i=0; i<cameraNum; i++) {
if(m_devicename==cameraList[i].SerialString && PvCameraOpen(cameraList[i].UniqueId, ePvAccessMaster, &m_grabber) == ePvErrSuccess) {
break;
}
}
}
if(NULL==m_grabber) {
verbose(1, "checking DisplayName: %s", m_devicename.c_str());
for(i=0; i<cameraNum; i++) {
if(m_devicename==cameraList[i].DisplayName && PvCameraOpen(cameraList[i].UniqueId, ePvAccessMaster, &m_grabber) == ePvErrSuccess) {
break;
}
}
}
if(NULL==m_grabber) {
struct addrinfo *result=NULL, *rp=NULL;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family=PF_INET;
if(0==getaddrinfo(m_devicename.c_str(), NULL, NULL, &result)) {
unsigned long OldAddr=0;
for(rp=result; rp!=NULL; rp=rp->ai_next) {
struct sockaddr_in*ipv4 = (struct sockaddr_in*)result->ai_addr;
unsigned long IpAddr=ipv4->sin_addr.s_addr ; // byte order??
if(OldAddr==IpAddr)continue;
OldAddr=IpAddr;
verbose(1, "AVT trying to connect to %3d.%3d.%3d.%3d",
(IpAddr & 0x0FF),
(IpAddr & 0x0FF00)>>8,
(IpAddr & 0x0FF0000)>>16,
(IpAddr & 0xFF000000)>>24
);
if(ePvErrSuccess == PvCameraOpenByAddr(IpAddr, ePvAccessMaster, &m_grabber)) {
break;
}
m_grabber=NULL;
}
freeaddrinfo(result);
}
}
}
delete[]cameraList;
if(m_grabber) {
unsigned long FrameSize = 0;
if(!PvAttrUint32Get(m_grabber,"TotalBytesPerFrame",&FrameSize)) {
resizeFrames(FrameSize);
} else {
close();
}
}
return (NULL!=m_grabber);
}
/////////////////////////////////////////////////////////
// closeDevice
//
/////////////////////////////////////////////////////////
void videoAVT :: closeDevice() {
if(m_grabber)PvCameraClose(m_grabber);
m_grabber=NULL;
}
/////////////////////////////////////////////////////////
// startTransfer
//
/////////////////////////////////////////////////////////
bool videoAVT :: startTransfer()
{
PvCaptureStart(m_grabber);
if(!PvCommandRun(m_grabber,"AcquisitionStart")) {
error("AVT::AcquistionStart failed");
} else {
PvCaptureQueueFrame(m_grabber, &m_frames[0], grabCB);
}
return true;
}
/////////////////////////////////////////////////////////
// stopTransfer
//
/////////////////////////////////////////////////////////
bool videoAVT :: stopTransfer()
{
PvCaptureQueueClear(m_grabber);
if(!PvCommandRun(m_grabber,"AcquisitionStop")) {
error("AVT::AcquistionStop failed");
}
PvCaptureEnd(m_grabber);
return true;
}
std::vector<std::string> videoAVT::enumerate() {
std::vector<std::string> result;
unsigned long cameraNum=PvCameraCount();
tPvCameraInfo*cameraList=new tPvCameraInfo[cameraNum];
cameraNum = PvCameraList(cameraList,cameraNum,NULL);
unsigned long i = 0;
for (i = 0; i < cameraNum; i++) {
result.push_back(cameraList[i].DisplayName);
}
delete[]cameraList;
return result;
}
bool videoAVT::enumProperties(gem::Properties&readable,
gem::Properties&writeable) {
tPvAttrListPtr listPtr;
unsigned long listLength;
if (PvAttrList(m_grabber, &listPtr, &listLength) == ePvErrSuccess) {
for (int i = 0; i < listLength; i++) {
const char* attributeName = listPtr[i];
std::cerr <<"Attribute["<<i<<"]: " << attributeName << std::endl;
tPvAttributeInfo pInfo;
if(ePvErrSuccess==PvAttrInfo(m_grabber, attributeName, &pInfo)) {
std::string name=attributeName;
gem::any type;
switch (pInfo.Datatype) {
case ePvDatatypeUnknown:
case ePvDatatypeRaw:
continue;
case ePvDatatypeCommand:
// type=notype;
break;
case ePvDatatypeString:
type=std::string("string");
break;
case ePvDatatypeEnum:
//PvAttrRangeEnum
type=0;
break;
case ePvDatatypeUint32:
//PvAttrRangeUint32
type=0;
break;
case ePvDatatypeFloat32:
//PvAttrRangeFloat32
type=0;
break;
case ePvDatatypeInt64:
//PvAttrRangeInt64
type=0;
break;
case ePvDatatypeBoolean:
type=1;
break;
}
if((pInfo.Flags & ePvFlagRead) || (pInfo.Flags & ePvFlagConst)) {
readable.set(name, type);
}
if(pInfo.Flags & ePvFlagWrite) {
writeable.set(name, type);
}
}
}
}
return true;
}
void videoAVT::setProperties(gem::Properties&props){
int i;
std::vector<std::string>keys=props.keys();
for(i=0; i<keys.size(); i++) {
tPvAttributeInfo pInfo;
std::string key=keys[i];
if(ePvErrSuccess!=PvAttrInfo(m_grabber, key.c_str(), &pInfo))
continue;
if(!(pInfo.Flags & ePvFlagWrite)) {
continue;
}
std::string s;
double d;
switch (pInfo.Datatype) {
default:
continue;
case ePvDatatypeCommand:
// type=notype;
break;
case ePvDatatypeString:
if(props.get(key, s)) {
PvAttrStringSet(m_grabber, key.c_str(), s.c_str());
}
break;
case ePvDatatypeEnum:
if(props.get(key, s)) {
PvAttrEnumSet(m_grabber, key.c_str(), s.c_str());
}
#if 0
else if(props.get(key, d)) {
std::vector<std::string>sv;
int index=d;
if(index<0)continue;
if (PvAttrRangeEnum(m_camera, "AcquisitionMode",
enumSet, sizeof(enumSet), NULL) == ePvErrSuccess) {
char* member = strtok(enumSet, ","); // strtok isn't always thread safe!
while (member != NULL) {
sv.push_back(member);
member = strtok(NULL, ",");
}
if(index>=sv.size()) {
continue;
}
PvAttrEnumSet(m_grabber, key.c_str(), sv[index].c_str());
}
#endif
break;
case ePvDatatypeUint32:
if(props.get(key, d)) {
tPvUint32 v=d;
PvAttrUint32Set(m_grabber, key.c_str(), d);
}
break;
case ePvDatatypeFloat32:
if(props.get(key, d)) {
tPvFloat32 v=d;
PvAttrFloat32Set(m_grabber, key.c_str(), d);
}
break;
case ePvDatatypeInt64:
if(props.get(key, d)) {
tPvInt64 v=d;
PvAttrInt64Set(m_grabber, key.c_str(), d);
}
break;
case ePvDatatypeBoolean:
if(props.get(key, d)) {
tPvBoolean v=d;
PvAttrBooleanSet(m_grabber, key.c_str(), d);
}
break;
}
} // loop
}
void videoAVT::getProperties(gem::Properties&props) {
int i;
std::vector<std::string>keys=props.keys();
for(i=0; i<keys.size(); i++) {
tPvAttributeInfo pInfo;
std::string key=keys[i];
if(ePvErrSuccess!=PvAttrInfo(m_grabber, key.c_str(), &pInfo))
continue;
if(!(pInfo.Flags & ePvFlagRead)) {
continue;
}
std::string s;
double d;
char svalue[MAXPDSTRING];
unsigned long size;
props.erase(key);
switch (pInfo.Datatype) {
default:
continue;
case ePvDatatypeString:
if (ePvErrSuccess==PvAttrStringGet(m_grabber, key.c_str(), svalue, MAXPDSTRING, &size)) {
s=svalue;
props.set(key, s);
}
break;
case ePvDatatypeEnum:
if (ePvErrSuccess==PvAttrEnumGet(m_grabber, key.c_str(), svalue, MAXPDSTRING, &size)) {
s=svalue;
props.set(key, s);
}
break;
case ePvDatatypeUint32: {
tPvUint32 value;
if (ePvErrSuccess==PvAttrUint32Get(m_grabber, key.c_str(), &value)) {
props.set(key, static_cast<double>(value));
}
}
break;
case ePvDatatypeFloat32: {
tPvFloat32 value;
if (ePvErrSuccess==PvAttrFloat32Get(m_grabber, key.c_str(), &value)) {
props.set(key, static_cast<double>(value));
}
}
break;
case ePvDatatypeInt64: {
tPvInt64 value;
if (ePvErrSuccess==PvAttrInt64Get(m_grabber, key.c_str(), &value)) {
props.set(key, static_cast<double>(value));
}
}
break;
case ePvDatatypeBoolean: {
tPvBoolean value;
if (ePvErrSuccess==PvAttrBooleanGet(m_grabber, key.c_str(), &value)) {
props.set(key, static_cast<double>(value));
}
}
break;
}
} // loop
}
#else
videoAVT :: videoAVT() : videoBase("")
{ }
videoAVT :: ~videoAVT()
{ }
#endif /* HAVE_AVT */