/////////////////////////////////////////////////////////////////////////////
// Copyright: (C) 2008-19 Cesar Mauri Loba - CREA Software Systems
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
/////////////////////////////////////////////////////////////////////////////
#include "crvcamera_cv.h"
#include
#include
#include
#include
#include
#include
bool CCameraCV::g_cvInitialized= false;
int CCameraCV::g_numDevices= 0;
char CCameraCV::g_deviceNames[MAX_CV_DEVICES][50];
#if defined(WIN32)
#include
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
// Workround to enable capture at 30fps for some camera models
// Should be called with administrative rights
// Return 0 if ok, -1 if permission denied
int VfwCamFpsWorkaround ()
{
HKEY hKey;
TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
DWORD cbName; // size of name string
TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
DWORD cchClassName = MAX_PATH; // size of class string
DWORD cSubKeys=0; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key
DWORD cchMaxValue; // longest value name
DWORD cbMaxValueData; // longest value data
DWORD cbSecurityDescriptor; // size of security descriptor
FILETIME ftLastWriteTime; // last write time
DWORD i, retCode;
// DWORD cchValue = MAX_VALUE_NAME;
// Open key
retCode= RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\VfWWDM Mapper"),
0, KEY_ALL_ACCESS, &hKey);
if (retCode!= ERROR_SUCCESS) return -1;
// Get the class name and the value count.
retCode = RegQueryInfoKey(
hKey, // key handle
achClass, // buffer for class name
&cchClassName, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
&cbMaxSubKey, // longest subkey size
&cchMaxClass, // longest class string
&cValues, // number of values for this key
&cchMaxValue, // longest value name
&cbMaxValueData, // longest value data
&cbSecurityDescriptor, // security descriptor
&ftLastWriteTime); // last write time
// Enumerate the subkeys
if (cSubKeys) {
for (i=0; i= GetNumDevices()) throw camera_exception("wrong camera id");
m_Id= cameraId;
m_Width= width;
m_Height= height;
m_FrameRate= fr;
m_pCvCapture= NULL;
#if defined(WIN32)
VfwCamFpsWorkaround ();
#endif
}
CCameraCV::~CCameraCV(void)
{
Close ();
}
bool CCameraCV::DoOpen ()
{
if (m_pCvCapture!= NULL) return true; // Already opened
m_pCvCapture= cvCreateCameraCapture(m_Id);
if (m_pCvCapture== NULL) return false;
// Try to set capture parameters although not always works
cvSetCaptureProperty( m_pCvCapture, CV_CAP_PROP_FRAME_WIDTH, (double) m_Width );
cvSetCaptureProperty( m_pCvCapture, CV_CAP_PROP_FRAME_HEIGHT, (double) m_Height );
// The following line does nothing under MS Windows
cvSetCaptureProperty( m_pCvCapture, CV_CAP_PROP_FPS, (double) m_FrameRate );
return true;
}
void CCameraCV::DoClose ()
{
if (m_pCvCapture== NULL) return; // Already closed
cvReleaseCapture (&m_pCvCapture);
m_pCvCapture= NULL;
}
IplImage *CCameraCV::DoQueryFrame()
{
assert (m_pCvCapture);
if (m_pCvCapture== NULL) return NULL;
IplImage *pImage= cvQueryFrame( m_pCvCapture );
if (pImage== NULL) return NULL;
#if defined(linux)
// It seems that under Linux no proper channelSeq is reported
// Tested with Logitech Quickcam pro 4000
pImage->channelSeq[0]= 'B';
pImage->channelSeq[2]= 'R';
#endif
return pImage;
}
int CCameraCV::GetNumDevices()
{
if (!g_cvInitialized) {
g_cvInitialized= true;
int i;
CvCapture* tmpCapture;
// Detect number of connected devices
for (i= 0; i< MAX_CV_DEVICES; ++i) {
tmpCapture= cvCreateCameraCapture (i);
if (tmpCapture== NULL) break;
cvReleaseCapture (&tmpCapture);
// Generate device name
sprintf (g_deviceNames[i], "Camera (Id:%d)", i);
}
g_numDevices= i;
}
return g_numDevices;
}
char* CCameraCV::GetDeviceName (unsigned int id)
{
if ((int) id>= GetNumDevices()) return NULL;
return g_deviceNames[id];
}