471 lines
12 KiB
C++
471 lines
12 KiB
C++
#include "GalaxyCamera.h"
|
||
#include <GL/mesa_gl.h>
|
||
#include <GL/glu.h>
|
||
#include <GL/khronos_glext.h>
|
||
#include "../config/ConfigManager.h"
|
||
#include <atlbase.h>
|
||
#include "../SystemInfo.h"
|
||
|
||
GalaxyCamera::GalaxyCamera()
|
||
:m_bIsOffline(true)
|
||
, m_EntityCount(0)
|
||
{
|
||
//InitializeCriticalSection(&m_rcs);
|
||
//初始化设备库
|
||
}
|
||
|
||
|
||
GalaxyCamera::~GalaxyCamera()
|
||
{
|
||
if (m_IsStaticInit) {
|
||
try {
|
||
ProcOffline();
|
||
//关闭设备库
|
||
m_EntityCount--;
|
||
if (m_EntityCount==0) {
|
||
IGXFactory::GetInstance().Uninit();
|
||
}
|
||
if (m_pDeviceOfflineEventHandle)delete m_pDeviceOfflineEventHandle;
|
||
}
|
||
catch (CGalaxyException &e) {
|
||
// g_log->TraceError("[%s]%d:%s", __FUNCTION__, e.GetErrorCode(), e.what());
|
||
}
|
||
catch (std::exception &e) {
|
||
//g_log->TraceError("[%s]%s", __FUNCTION__, e.what());
|
||
}
|
||
|
||
// if (m_pDeviceOfflineEventHandle)
|
||
// delete m_pDeviceOfflineEventHandle;
|
||
}
|
||
|
||
}
|
||
|
||
bool GalaxyCamera::Init()
|
||
{
|
||
bool rel = true;
|
||
m_pDeviceOfflineEventHandle = new CameraDeviceOfflineEventHandle();
|
||
if (!m_IsStaticInit) {
|
||
try {
|
||
IGXFactory::GetInstance().Init();
|
||
m_IsStaticInit = true;
|
||
}
|
||
catch (CGalaxyException &e) {
|
||
|
||
rel = false;
|
||
}
|
||
catch (std::exception &e) {
|
||
rel = false;
|
||
}
|
||
}
|
||
m_EntityCount++;
|
||
return rel;
|
||
}
|
||
|
||
bool GalaxyCamera::ConnectCamera()
|
||
{
|
||
bool rel = true;
|
||
bool bIsDeviceOpen = false; ///< 设备是否已打开标识
|
||
bool bIsStreamOpen = false; ///< 设备流是否已打开标识
|
||
try {
|
||
//子网枚举设备
|
||
GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;
|
||
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
|
||
//判断当前设备连接个数
|
||
if (vectorDeviceInfo.size() <= 0) {
|
||
return false;
|
||
}
|
||
m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(vectorDeviceInfo[0].GetSN(), GX_ACCESS_EXCLUSIVE);
|
||
//m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceByIP(GxIAPICPP::gxstring(m_IP.c_str()), GX_ACCESS_EXCLUSIVE);
|
||
bIsDeviceOpen = true;
|
||
m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();
|
||
int32_t nStreamCount = m_objDevicePtr->GetStreamCount();
|
||
if (nStreamCount == 0) {
|
||
return false;
|
||
}
|
||
|
||
m_objStreamPtr = m_objDevicePtr->OpenStream(0);
|
||
bIsStreamOpen = true;
|
||
|
||
if (m_ExtCfg->m_IsExposureAuto) {
|
||
m_objFeatureControlPtr->GetEnumFeature("ExposureAuto")->SetValue("Continuous");
|
||
}
|
||
if (m_ExtCfg->m_IsGainAuto) {
|
||
m_objFeatureControlPtr->GetEnumFeature("GainAuto")->SetValue("Continuous");
|
||
}
|
||
if (m_ExtCfg->m_IsCameralColorful)m_objFeatureControlPtr->GetEnumFeature("BalanceWhiteAuto")->SetValue("Continuous");
|
||
|
||
//设置心跳超时时间为1s
|
||
//针对千兆网相机,程序在Debug模式下调试运行时,相机的心跳超时时间自动设置为5min,
|
||
//这样做是为了不让相机的心跳超时影响程序的调试和单步执行,同时这也意味着相机在这5min内无法断开,除非使相机断电再上电
|
||
//为了解决掉线重连问题,将相机的心跳超时时间设置为1s,方便程序掉线后可以重新连接
|
||
m_objFeatureControlPtr->GetIntFeature("GevHeartbeatTimeout")->SetValue(1000);
|
||
m_hCB = m_objDevicePtr->RegisterDeviceOfflineCallback(m_pDeviceOfflineEventHandle, this);
|
||
m_bIsOpen = true;
|
||
|
||
m_objStreamPtr->StartGrab();
|
||
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
|
||
m_bIsSnap = true;
|
||
m_bIsOffline = false;
|
||
}
|
||
catch (CGalaxyException &e) {
|
||
if (bIsStreamOpen)
|
||
{
|
||
m_objStreamPtr->Close();
|
||
}
|
||
if (bIsDeviceOpen)
|
||
{
|
||
m_objDevicePtr->Close();
|
||
}
|
||
rel = false;
|
||
}
|
||
catch (std::exception &e) {
|
||
if (bIsStreamOpen)
|
||
{
|
||
m_objStreamPtr->Close();
|
||
}
|
||
if (bIsDeviceOpen)
|
||
{
|
||
m_objDevicePtr->Close();
|
||
}
|
||
rel = false;
|
||
}
|
||
return rel;
|
||
}
|
||
|
||
|
||
GX_VALID_BIT_LIST GalaxyCamera::GetBestValudBit(GX_PIXEL_FORMAT_ENTRY emPixelFormatEntry)
|
||
{
|
||
GX_VALID_BIT_LIST emValidBits = GX_BIT_0_7;
|
||
switch (emPixelFormatEntry)
|
||
{
|
||
case GX_PIXEL_FORMAT_MONO8:
|
||
case GX_PIXEL_FORMAT_BAYER_GR8:
|
||
case GX_PIXEL_FORMAT_BAYER_RG8:
|
||
case GX_PIXEL_FORMAT_BAYER_GB8:
|
||
case GX_PIXEL_FORMAT_BAYER_BG8:
|
||
{
|
||
emValidBits = GX_BIT_0_7;
|
||
break;
|
||
}
|
||
case GX_PIXEL_FORMAT_MONO10:
|
||
case GX_PIXEL_FORMAT_BAYER_GR10:
|
||
case GX_PIXEL_FORMAT_BAYER_RG10:
|
||
case GX_PIXEL_FORMAT_BAYER_GB10:
|
||
case GX_PIXEL_FORMAT_BAYER_BG10:
|
||
{
|
||
emValidBits = GX_BIT_2_9;
|
||
break;
|
||
}
|
||
case GX_PIXEL_FORMAT_MONO12:
|
||
case GX_PIXEL_FORMAT_BAYER_GR12:
|
||
case GX_PIXEL_FORMAT_BAYER_RG12:
|
||
case GX_PIXEL_FORMAT_BAYER_GB12:
|
||
case GX_PIXEL_FORMAT_BAYER_BG12:
|
||
{
|
||
emValidBits = GX_BIT_4_11;
|
||
break;
|
||
}
|
||
case GX_PIXEL_FORMAT_MONO14:
|
||
{
|
||
//暂时没有这样的数据格式待升级
|
||
break;
|
||
}
|
||
case GX_PIXEL_FORMAT_MONO16:
|
||
case GX_PIXEL_FORMAT_BAYER_GR16:
|
||
case GX_PIXEL_FORMAT_BAYER_RG16:
|
||
case GX_PIXEL_FORMAT_BAYER_GB16:
|
||
case GX_PIXEL_FORMAT_BAYER_BG16:
|
||
{
|
||
//暂时没有这样的数据格式待升级
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
return emValidBits;
|
||
}
|
||
|
||
void GalaxyCamera::CatpureRun(void)
|
||
{
|
||
while (m_RunFlag) {
|
||
try {
|
||
if (m_bIsOffline) {
|
||
ProcOffline();
|
||
int count = 0;
|
||
while (m_RunFlag && count < 25) {
|
||
count++;
|
||
Sleep(200);
|
||
}
|
||
if (!m_RunFlag)break;
|
||
ConnectCamera();
|
||
if (m_bIsOffline) {
|
||
continue;
|
||
}
|
||
}
|
||
bool rel = (m_ShowFlag || m_DemandFlag);
|
||
if (rel) {
|
||
CImageDataPointer objImageDataPointer = m_objStreamPtr->GetImage(300);
|
||
if (objImageDataPointer->GetStatus() == GX_FRAME_STATUS_SUCCESS)
|
||
{
|
||
EnterCriticalSection(&m_OriginalDataCS);
|
||
m_objImageDataPtr = objImageDataPointer;
|
||
GX_VALID_BIT_LIST emValidBits = GetBestValudBit(m_objImageDataPtr->GetPixelFormat());
|
||
if (m_ExtCfg->m_IsCameralColorful) {
|
||
m_OriginalData = (unsigned char*)m_objImageDataPtr->ConvertToRGB24(emValidBits, GX_RAW2RGB_NEIGHBOUR, false);
|
||
}
|
||
else m_OriginalData = (unsigned char*)m_objImageDataPtr->ConvertToRaw8(emValidBits);
|
||
|
||
m_OriginalWidth = m_objImageDataPtr->GetWidth();
|
||
m_OriginalHeight = m_objImageDataPtr->GetHeight();
|
||
m_ImageChanged = true;
|
||
LeaveCriticalSection(&m_OriginalDataCS);
|
||
}
|
||
}
|
||
}
|
||
catch (CGalaxyException &e)
|
||
{
|
||
|
||
}
|
||
catch (std::exception &e)
|
||
{
|
||
|
||
}
|
||
Sleep(80);
|
||
}
|
||
}
|
||
|
||
|
||
void GalaxyCamera::ProcOffline()
|
||
{
|
||
try
|
||
{
|
||
//判断设备是否停止采集
|
||
if (m_bIsSnap)
|
||
{
|
||
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
|
||
m_objStreamPtr->StopGrab();
|
||
m_bIsSnap = false;
|
||
}
|
||
}
|
||
catch (CGalaxyException &e)
|
||
{
|
||
|
||
}
|
||
catch (std::exception &e)
|
||
{
|
||
|
||
}
|
||
|
||
try
|
||
{
|
||
//判断设备是否打开
|
||
if (m_bIsOpen)
|
||
{
|
||
//注销掉线回调函数
|
||
m_objDevicePtr->UnregisterDeviceOfflineCallback(m_hCB);
|
||
//关闭流和设备
|
||
m_objStreamPtr->Close();
|
||
m_objDevicePtr->Close();
|
||
m_bIsOpen = false;
|
||
|
||
}
|
||
}
|
||
catch (CGalaxyException)
|
||
{
|
||
//do noting
|
||
}
|
||
catch (std::exception)
|
||
{
|
||
//do noting
|
||
}
|
||
|
||
}
|
||
|
||
bool GalaxyCamera::GenLogImage(void)
|
||
{
|
||
if (m_bIsOffline)
|
||
return false;
|
||
|
||
if (!m_DemandFlag)
|
||
return false;
|
||
|
||
if (!m_OriginalData)
|
||
return false;
|
||
|
||
EnterCriticalSection(&m_OriginalDataCS);
|
||
float ratio = ConfigManager::GetInstance()->GetExtCfg()->m_LogRatio;
|
||
if (m_LogImage) {
|
||
tjFree(m_LogImage);
|
||
}
|
||
m_LogImage = NULL;
|
||
unsigned char* ptmp = nullptr;
|
||
|
||
|
||
if (m_ExtCfg->m_IsCameralColorful) {
|
||
tjCompress2(m_tjinstance, m_OriginalData, m_OriginalWidth, 0, m_OriginalHeight, TJPF_RGB, &ptmp, &m_LogImageSize, TJSAMP_422, 70, TJFLAG_BOTTOMUP);
|
||
}
|
||
else {
|
||
tjCompress2(m_tjinstance, m_OriginalData, m_OriginalWidth, 0, m_OriginalHeight, TJPF_GRAY, &ptmp, &m_LogImageSize, TJSAMP_GRAY, 70, TJFLAG_BOTTOMUP);
|
||
}
|
||
|
||
tjDestroy(m_tjinstance);
|
||
m_tjinstance = nullptr;
|
||
m_tjinstance = tjInitDecompress();
|
||
int comwidth = m_OriginalWidth*ratio;
|
||
int comheight = m_OriginalHeight*ratio;
|
||
unsigned char* ptmp2 = NULL;
|
||
if (m_ExtCfg->m_IsCameralColorful) {
|
||
ptmp2 = tjAlloc(comwidth * comheight * tjPixelSize[TJPF_RGB]);
|
||
tjDecompress2(m_tjinstance, ptmp, m_LogImageSize, ptmp2, comwidth, 0, comheight, TJPF_RGB, 0);
|
||
tjDestroy(m_tjinstance);
|
||
m_tjinstance = nullptr;
|
||
m_tjinstance = tjInitCompress();
|
||
tjCompress2(m_tjinstance, ptmp2, comwidth, 0, comheight, TJPF_RGB, &m_LogImage, &m_LogImageSize, TJSAMP_422, 60, TJFLAG_BOTTOMUP);
|
||
|
||
}
|
||
else {
|
||
ptmp2 = tjAlloc(comwidth * comheight * tjPixelSize[TJPF_GRAY]);
|
||
tjDecompress2(m_tjinstance, ptmp, m_LogImageSize, ptmp2, comwidth, 0, comheight, TJPF_GRAY, 0);
|
||
tjDestroy(m_tjinstance);
|
||
m_tjinstance = nullptr;
|
||
m_tjinstance = tjInitCompress();
|
||
tjCompress2(m_tjinstance, ptmp2, comwidth, 0, comheight, TJPF_GRAY, &m_LogImage, &m_LogImageSize, TJSAMP_GRAY, 60, TJFLAG_BOTTOMUP);
|
||
}
|
||
|
||
tjFree(ptmp);
|
||
tjFree(ptmp2);
|
||
LeaveCriticalSection(&m_OriginalDataCS);
|
||
return true;
|
||
}
|
||
|
||
void GalaxyCamera::GenTex(uint32_t *tex, unsigned int w, unsigned int h, void * data)
|
||
{
|
||
glGenTextures(1, tex);
|
||
if (*tex > 0) {
|
||
glBindTexture(GL_TEXTURE_2D, *tex);
|
||
//glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||
if (m_ExtCfg->m_IsCameralColorful) {
|
||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, data);
|
||
}
|
||
else {
|
||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
|
||
}
|
||
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||
glBindTexture(GL_TEXTURE_2D, 0);
|
||
}
|
||
}
|
||
|
||
GLuint GalaxyCamera::GetShowImage(void)
|
||
{
|
||
if (m_bIsOffline)
|
||
return 0;
|
||
|
||
if (!m_ImageChanged)
|
||
return m_GLTex;
|
||
|
||
if (TryEnterCriticalSection(&m_OriginalDataCS)) {
|
||
if (m_GLTex == 0) {
|
||
m_ImgWidth = m_OriginalWidth;
|
||
m_ImgHeight = m_OriginalHeight;
|
||
m_Aspect = (float)m_ImgWidth / m_ImgHeight;
|
||
GenTex(&m_GLTex, m_ImgWidth, m_ImgHeight, m_OriginalData);
|
||
}
|
||
else if (m_OriginalWidth != m_ImgWidth || m_OriginalHeight != m_ImgHeight) {
|
||
m_ImgWidth = m_OriginalWidth;
|
||
m_ImgHeight = m_OriginalHeight;
|
||
m_Aspect = (float)m_ImgWidth / m_ImgHeight;
|
||
glDeleteTextures(1, &m_GLTex);
|
||
GenTex(&m_GLTex, m_ImgWidth, m_ImgHeight, m_OriginalData);
|
||
}
|
||
else {
|
||
glBindTexture(GL_TEXTURE_2D, m_GLTex);
|
||
//glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||
if (m_ExtCfg->m_IsCameralColorful) {
|
||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_ImgWidth, m_ImgHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, m_OriginalData);
|
||
}
|
||
else {
|
||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_ImgWidth, m_ImgHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_OriginalData);
|
||
}
|
||
|
||
//glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_ImgWidth, m_ImgHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_OriginalData);
|
||
glBindTexture(GL_TEXTURE_2D, 0);
|
||
}
|
||
m_ImageChanged = false;
|
||
LeaveCriticalSection(&m_OriginalDataCS);
|
||
}
|
||
|
||
return m_GLTex;
|
||
}
|
||
|
||
unsigned int GalaxyCamera::GetShowImage(unsigned char * data, unsigned long size, int *width, int *height)
|
||
{
|
||
if (data == NULL || size == 0)
|
||
return 0;
|
||
|
||
int inSubsamp, inColorspace;
|
||
tjhandle tjInstance = tjInitDecompress();
|
||
if (tjDecompressHeader3(tjInstance, data, size, width, height,
|
||
&inSubsamp, &inColorspace) < 0) {
|
||
tjDestroy(tjInstance);
|
||
return 0;
|
||
}
|
||
|
||
unsigned char * ptmp;
|
||
if (m_ExtCfg->m_IsCameralColorful) {
|
||
ptmp = tjAlloc((*width) * (*height) * tjPixelSize[TJPF_RGB]);
|
||
if (tjDecompress2(tjInstance, data, size, ptmp, *width, 0, *height, TJPF_RGB, 0) < 0) {
|
||
tjFree(ptmp);
|
||
tjDestroy(tjInstance);
|
||
return 0;
|
||
}
|
||
}
|
||
else {
|
||
ptmp = tjAlloc((*width) * (*height) * tjPixelSize[TJPF_GRAY]);
|
||
if (tjDecompress2(tjInstance, data, size, ptmp, *width, 0, *height, TJPF_GRAY, 0) < 0) {
|
||
tjFree(ptmp);
|
||
tjDestroy(tjInstance);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
tjDestroy(tjInstance);
|
||
|
||
glDeleteTextures(1, &m_LogGLTex);
|
||
GenTex(&m_LogGLTex, *width, *height, ptmp);
|
||
|
||
tjFree(ptmp);
|
||
return m_LogGLTex;
|
||
}
|
||
|
||
void GalaxyCamera::SetExposureAutoByCfg()
|
||
{
|
||
if (m_bIsOffline)return;
|
||
if (m_ExtCfg->m_IsExposureAuto) m_objFeatureControlPtr->GetEnumFeature("ExposureAuto")->SetValue("Continuous");
|
||
else m_objFeatureControlPtr->GetEnumFeature("ExposureAuto")->SetValue("Off");
|
||
}
|
||
|
||
void GalaxyCamera::SetExposureTimeByCfg()
|
||
{
|
||
if (m_bIsOffline)return;
|
||
m_objFeatureControlPtr->GetFloatFeature("ExposureTime")->SetValue(m_ExtCfg->m_ExposureTime);
|
||
}
|
||
|
||
void GalaxyCamera::SetGainAuto()
|
||
{
|
||
if (m_bIsOffline)return;
|
||
if (m_ExtCfg->m_IsGainAuto) {
|
||
m_objFeatureControlPtr->GetEnumFeature("GainAuto")->SetValue("Continuous");
|
||
}
|
||
else m_objFeatureControlPtr->GetEnumFeature("GainAuto")->SetValue("Off");
|
||
|
||
}
|
||
|
||
|
||
bool GalaxyCamera::m_IsStaticInit = false; |