📄 camera.cpp
字号:
*/
//------------------------------------------------------------------------------
void CCamera::CreateThreads()
{
if ( HANDLE(m_DisplayThread) == NULL )
{
// create display thread
if ( ! m_DisplayThread.Create(THREAD_PRIORITY_BELOW_NORMAL) )
{
throw BcamException(::GetLastError(), "CCamera: Create Display Thread");
}
}
if ( HANDLE(m_AcquisitionThread) == NULL && IsOpen() )
{
// create acquisition thread
if ( ! m_AcquisitionThread.Create(THREAD_PRIORITY_TIME_CRITICAL) )
{
throw BcamException(::GetLastError(), "CCamera: Create Acquisition Thread");
}
}
}
//------------------------------------------------------------------------------
// void CCamera::DestroyThreads()
// Author:
//------------------------------------------------------------------------------
/**
* - Destroy the threads
*/
//------------------------------------------------------------------------------
void CCamera::DestroyThreads()
{
m_AcquisitionThread.Destroy();
m_DisplayThread.Destroy();
}
/**
* Allocate buffer
* Allocate resources
*
* \return
*
* void
*
*/
//------------------------------------------------------------------------------
void CCamera::StartSingleGrab(eState stateToEnter)
{
assert(m_State == sIdle);
CAutoLock<CCriticalSection> lockAcqu(m_csAcquisition);
m_DisplayThread.SetBuffer(NULL);
m_fBitmapValid = false;
// Setup associated image window
m_pChildFrame->m_View.ConfigurationChanged(m_VideoFormat, m_VideoMode, m_SensorSize, m_ImageSize, m_Origin);
CreateNewBuffers(1); // old buffers will be released
// Allocate BCAM resources
AllocateResources(1, m_ppBuffers[0]->GetBufferSize());
// Create display and acquisition thread when not already running
CreateThreads();
// State transition
m_State = stateToEnter;
// Issue One Shot
Enqueue(
m_ppBuffers[0],
true // issue one shot command
);
}
//------------------------------------------------------------------------------
// void CCamera::PrepareContinuousGrab()
// Author:
//------------------------------------------------------------------------------
/**
* Allocate buffers
* Enqueue buffers in driver's queue
* Initialize measurment of frame rates
* Switch camera to ISO enable mode
*
* \return
*
* void
*
*/
//------------------------------------------------------------------------------
void CCamera::PrepareContinuousGrab(bool invalidate)
{
assert(m_State == sIdle || m_State == sContinuousGrabSuspended );
CAutoLock<CCriticalSection> lockAcqu(m_csAcquisition);
if ( invalidate )
m_fBitmapValid = false;
if ( m_pChildFrame != NULL )
m_pChildFrame->m_View.ConfigurationChanged(m_VideoFormat, m_VideoMode, m_SensorSize, m_ImageSize, m_Origin);
// Allocate new buffers ( existing ones will be released )
CreateNewBuffers(4);
// Allocate 1394 resources (bandwith and isochronous channel)
AllocateResources(m_cBuffers, m_ppBuffers[0]->GetBufferSize());
// queue in all buffers
for ( int i = 0; i < m_cBuffers ; i++)
{
Enqueue(m_ppBuffers[i]);
}
m_DisplayThread.SetBuffer(NULL);
m_DisplayAvg.Reset();
m_AcquisitionAvg.Reset();
}
//------------------------------------------------------------------------------
// void CCamera::CreateNewBuffers(unsigned long n)
// Author:
//------------------------------------------------------------------------------
/**
* Allocate new buffers. Currently allocated buffers are freed
*
* \param n Number of buffers to allocate
* \return void
*
*/
//------------------------------------------------------------------------------
void CCamera::CreateNewBuffers(unsigned long n)
{
switch ( m_ColorCode )
{
case DCSColor_Mono8:
case DCSColor_Raw8:
case DCSColor_YUV8_4_2_2:
case DCSColor_RGB8:
break;
default:
throw BcamException(E_UNSUPPORTED_COLOR_CODE, "CCamera::CreateNewBuffers", &BcamUtility::ColorCodeName(m_ColorCode) );
}
try
{
// Release old buffers
ReleaseBuffers();
m_ppBuffers = new CBcamBitmap*[n];
if ( m_ppBuffers == NULL )
{
throw BcamException(E_OUTOFMEMORY, "CCamera::CreateNewBuffers()");
}
ZeroMemory(m_ppBuffers, n * sizeof(CBcamBitmap*));
m_cBuffers = n;
for ( unsigned long i = 0; i < n; i++)
{
m_ppBuffers[i] = new CBcamBitmap(m_ImageSize, m_SensorSize, m_Origin, m_ColorCode);
if ( m_ppBuffers[i] == NULL )
throw BcamException(E_OUTOFMEMORY, "CCamera::CreateNewBuffers()");
}
// Create new bitmap for display purposes
// first free an existing one
if ( m_pBitmap != NULL )
{
delete m_pBitmap;
m_pBitmap = NULL;
m_fBitmapValid = false;
}
// We will only allocate an extra bitmap to display, if the camera sends image data
// in a format we must convert. If no conversion is needed, no extra memory
// for the display bitmap will be allocated. Instead the grab functions have to ensure that
// m_pBitmap points to one of the buffers stored in m_ppBuffers.
if ( ( ! IsMono() || m_ConvertMono8ToRGB ) && m_ColorCode != DCSColor_RGB8 )
{
// create a new Bitmap to display
m_pBitmap = new CBcamBitmap(m_ImageSize, m_SensorSize, m_Origin, DCSColor_RGB8);
if ( m_pBitmap == NULL )
throw BcamException(E_OUTOFMEMORY, "CCamera::CreateBewBuffers()");
}
}
catch (BcamException& e)
{
ReleaseBuffers();
throw e;
}
}
//------------------------------------------------------------------------------
// void CCamera::ReleaseBuffers()
// Author:
//------------------------------------------------------------------------------
/**
* Free buffers.
*
* \return void
*
*/
//------------------------------------------------------------------------------
void CCamera::ReleaseBuffers()
{
CAutoLock<CCriticalSection> lockAcqu(m_csAcquisition);
if ( m_ppBuffers != NULL )
{
for ( int i = 0; i < m_cBuffers; i ++ )
{
if ( m_ppBuffers[i] != NULL && m_ppBuffers[i] != m_pBitmap )
{
delete m_ppBuffers[i];
}
}
delete[] m_ppBuffers;
m_ppBuffers = NULL;
m_cBuffers = 0;
}
}
//------------------------------------------------------------------------------
// void CCamera::Enqueue(CBcamBitmap* pBitmap)
// Author:
//------------------------------------------------------------------------------
/**
* Enqueue a buffer in the driver's queue
*
* \param pBitmap
* \return void
*
*/
//------------------------------------------------------------------------------
void CCamera::Enqueue(CBcamBitmap* pBitmap, bool singleShot )
{
# if VERBOSE
ATLTRACE("Enque %x\n", pBitmap);
#endif
GrabImageAsync(*pBitmap, pBitmap->GetBufferSize(), pBitmap, singleShot);
}
//------------------------------------------------------------------------------
// void CCamera::OnContinuousGrabError(DWORD err)
// Author:
//------------------------------------------------------------------------------
/**
* Callback. It is called if an error occured in one of the threads
*
* \param err error code
* \return
*
* <type Return description here>
*
*/
//------------------------------------------------------------------------------
void CCamera::OnContinuousGrabError(DWORD err)
{
BcamException e(err, "Image acquisition");
m_MainFrame.ReportError(e);
if ( m_State != sIdle )
GrabCancel();
m_fSurpressFurtherErrorMessages = false;
}
//------------------------------------------------------------------------------
// void CCamera::CancelContinuousGrab()
// Author:
//------------------------------------------------------------------------------
/**
* Cancel an active continuous grab. The acquisition thread will be terminated.
*
* \return error code. 0 indicates success
*/
//------------------------------------------------------------------------------
DWORD CCamera::CancelContinuousGrab()
{
CAutoLock<CCriticalSection> lock(m_csAcquisition);
DWORD error = 0;
m_State = sIdle;
try
{
Cancel(); // cancel I/O requests
}
catch ( BcamException& e )
{
error = e.Error();
if ( error != ERROR_DEVICE_REMOVED )
throw e;
}
// free resources
if ( ! error )
{
try
{
if ( IsBandwidthAllocated() )
FreeResources();
}
catch ( BcamException& e)
{
if ( e.Error() != ERROR_DEVICE_REMOVED )
error = e.Error();
}
}
return error;
}
//------------------------------------------------------------------------------
// void CCamera::AlignAOI(CSize& Size, DCSVideoMode mode)
// Author:
//------------------------------------------------------------------------------
/**
* Ensure that the given AOI size has a width beeing a multiple of 4, because the length of a bitmap's scanline
* is a multiple of 4
*
* \param Size
* \param mode
* \return void
*
*/
//------------------------------------------------------------------------------
void CCamera::AlignAOI(CSize& Size, DCSVideoMode mode)
{
CSize SizeInc;
const int WidthInc = lcm(4, FormatSeven[mode].Size.Inc().cx);
Size.cx = WidthInc * ( Size.cx / WidthInc );
}
//------------------------------------------------------------------------------
// void CCamera::ConvertBitmap(CBcamBitmap* *ppDest, CBcamBitmap* *ppSource)
// Author:
//------------------------------------------------------------------------------
/**
* If required, convert raw Bayer8 or YUV422 data into a 24 bit RGB bitmap
*
* \param *ppDest
* \param *ppSource
* \return void
*
*/
//------------------------------------------------------------------------------
void CCamera::ConvertBitmap(CBcamBitmap* *ppDest, CBcamBitmap* *ppSource)
{
switch ( m_ColorCode )
{
case DCSColor_Mono8 :
case DCSColor_Raw8:
if ( m_ConvertMono8ToRGB )
{
// Bayer -> RGB conversion
Bvc::CColorConverter::ConvertMono8ToRGB(**ppDest, **ppSource, (*ppDest)->GetSize(), (Bvc::CColorConverter::PatternOrigin_t) m_ConvertMono8ToRGB, m_pLutR, m_pLutG, m_pLutB);
}
else
{
// Nothing to be done ( mono8 image data). Let the bitmap point to the raw data
*ppDest = *ppSource;
}
break;
case DCSColor_YUV8_4_2_2 :
Bvc::CColorConverter::ConvertYUV422ToRGB(**ppDest, **ppSource, (*ppDest)->GetSize());
break;
default:
throw BcamException(E_UNSUPPORTED_COLOR_CODE, "CCamera::ConvertBitmap", &BcamUtility::ColorCodeName(m_ColorCode) );
}
}
//------------------------------------------------------------------------------
// void CCamera::SaveConfiguration(const CPropertyBagPtr ptrBag)
// Author:
// Date: 06.09.2002
//------------------------------------------------------------------------------
/**
* Save the current settings to a property bag.
*
* A client should not use the CBcam's SaveSettings methods, because we have to store
* additional information
*
* \param ptrBag
*/
//------------------------------------------------------------------------------
void CCamera::SaveConfiguration(const CPropertyBagPtr ptrBag)
{
CBcam::SaveSettings(ptrBag);
CPropertyBagPtr ptrBcamViewerBag = ptrBag->CreateBag("BcamViewer");
ptrBcamViewerBag->WriteLong("ConvertBayer8", m_ConvertMono8ToRGB);
ptrBcamViewerBag->WriteFloat("RGain", (float) m_GainR);
ptrBcamViewerBag->WriteFloat("BGain", (float) m_GainB);
}
//------------------------------------------------------------------------------
// void CCamera::RestoreConfiguration(const CPropertyBagPtr ptrBag)
// Author:
// Date: 06.09.2002
//------------------------------------------------------------------------------
/**
* Restore the current settings from a property bag.
*
*
* \param ptrBag
*/
//------------------------------------------------------------------------------
void CCamera::RestoreConfiguration(const CPropertyBagPtr ptrBag)
{
if ( ReconfigurationRequest() )
{
CBcam::RestoreSettings(ptrBag);
try
{
CPropertyBagPtr ptrBcamViewerBag = ptrBag->GetBag("BcamViewer");
m_ConvertMono8ToRGB = ptrBcamViewerBag->ReadLong("ConvertBayer8");
SetRGain(ptrBcamViewerBag->ReadFloat("RGain"));
SetBGain(ptrBcamViewerBag->ReadFloat("BGain"));
}
catch ( BcamException& )
{
// Additional information for bcam viewer not found.
// Nothing to be done;
}
// Refresh the cached information and notify clients of changes
Refresh(true);
ConfigurationChanged();
}
}
CCamera::CDisplayThread::CDisplayThread(CCamera* pParent)
: CThread()
, Parent(pParent)
, m_pNextBuffer(NULL)
{
// create events
if ( ! m_evtNewBufferAvailable.Create() )
{
throw BcamException(::GetLastError(), "CCamera: Create Event");
}
if ( ! m_evtTerminate.Create() )
{
throw BcamException(::GetLastError(), "CCamera: Create Event");
}
if ( ! m_evtCancelRequest.Create() )
{
throw BcamException(::GetLastError(), "CCamera: Create Event");
}
if ( ! m_evtCancelComplete.Create() )
{
throw BcamException(::GetLastError(), "CCamera: Create Event");
}
}
BOOL CCamera::CDisplayThread::Create(int Priority)
{
return CThread::Create(&ThreadProc, this, Priority, 0);
}
/**
* Thread procedure of the display thread.
*
*/
//------------------------------------------------------------------------------
DWORD CCamera::CDisplayThread::ThreadProc(void* pParameter)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -