The continuous acquisition is similar to the single capture. There is only one difference, this capture is implemented inside a thread.
Sending multiple request buffers to the driver has the advantage that while the application is busy processing a frame the driver can already capture the next one in the background.
Waiting for a buffer to become ready works by calling the DMR_ImageRequestWaitFor function:
Now you have the image and e.g. you can display it.
After processing the image you have to unlock the image buffer otherwise the driver will no longer be able to use it and send it back into the drivers request queue:
To show how to access and modify properties the capture thread will be executed twice. Once using only a quarter of the full sensor resolution and once using the full resolution. Once a key has been pressed the AOI will be re-programmed:
Please note that features such as the AOI that will affect the capture buffer size cannot be modified while requests are being processed by the driver, thus in order to change the AOI the capture thread must be stopped and all buffers must be unlocked:
#include <apps/Common/exampleHelper_C.h>
#include <mvDeviceManager/Include/mvDeviceManager.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
# include <conio.h>
# include <mvDisplay/Include/mvDisplayExtensions.h>
# include <mvDisplay/Include/mvDisplayWindow.h>
# include <process.h>
# include <windows.h>
# define USE_MV_DISPLAY_LIB
# define LIVE_LOOP_CALL __stdcall
#elif defined(linux) || defined(__linux) || defined(__linux__) || defined(__APPLE__)
# include <string.h>
# include <unistd.h>
# define LIVE_LOOP_CALL
# if defined(__x86_64__) || defined(__powerpc64__) || defined(__aarch64__)
typedef uint64_t UINT_PTR;
# elif defined(__i386__) || defined(__arm__) || defined(__powerpc__)
typedef uint32_t UINT_PTR;
# else
# error unsupported target platform
# endif
#else
# error unsupported target platform
#endif
#define BUF_SIZE (512)
static int s_boTerminated = 0;
typedef struct CaptureParameter
{
HDRV hDrv;
#ifdef USE_MV_DISPLAY_LIB
HDISP hDisp;
#endif
} CaptureParameter;
unsigned int LIVE_LOOP_CALL liveLoop( void* pData )
{
#ifdef USE_MV_DISPLAY_LIB
TDisp* pDisp;
#endif
int frameCount;
double fps;
int errorCount;
int requestNr;
int lastRequestNr;
hDrv = ( ( CaptureParameter* )pData )->hDrv;
#ifdef USE_MV_DISPLAY_LIB
#endif
pIB = 0;
frameCount = 0;
fps = 0.0;
requestNr = -1;
lastRequestNr = -1;
if( ( ( hPropFPS = getStatisticProp( hDrv,
"FramesPerSecond" ) ) ==
INVALID_ID ) ||
( ( hErrorCount = getStatisticProp( hDrv,
"ErrorCount" ) ) ==
INVALID_ID ) )
{
printf( "Unable to continue!\n" );
return 0;
}
{
printf(
"DMR_ImageRequestSingle: Unexpected error(code: %d(%s))\n", result,
DMR_ErrorCodeToString( result ) );
}
manuallyStartAcquisitionIfNeeded( hDrv );
while( !s_boTerminated )
{
const int timeout_ms = 500;
int overallTimeWaited_ms = 0;
{
{
frameCount = frameCount + 1;
{
if( ( frameCount % 100 ) == 0 )
{
OBJ_GetI( hErrorCount, &errorCount, 0 );
printf(
"Frames per second: %.5f, Width: %d, Height: %d, Error count: %d.\n", fps, pIB->
iWidth, pIB->
iHeight, errorCount );
}
#ifdef USE_MV_DISPLAY_LIB
#endif
}
else
{
}
}
else
{
printf(
"DMR_GetImageRequestResult: ERROR! Return value: %d(%s), request result: %d.\n", result,
DMR_ErrorCodeToString( result ), requestResult.
result );
}
if( lastRequestNr >= 0 )
{
}
lastRequestNr = requestNr;
}
else
{
overallTimeWaited_ms += timeout_ms;
printf(
"DMR_ImageRequestWaitFor failed(code: %d(%s)), meaning no buffer became ready after %d ms\n", result,
DMR_ErrorCodeToString( result ), overallTimeWaited_ms );
printf( "Please note that slow systems or interface technologies in combination with\n" );
printf( "high resolution sensors might need more time to transmit an image in %d ms.\n", timeout_ms );
printf( "If this is the case increase the timeout and rebuild this application or simply wait multiple times.\n" );
printf( "Once the camera is configured for triggered image acquisition and the timeout elapsed\n before the camera has been triggered this might happen as well.\n" );
}
#ifdef linux
s_boTerminated = waitForInput( 0, STDOUT_FILENO ) == 0 ? 0 : 1;
if( s_boTerminated == 1 )
{
fgetc( stdin );
}
#endif
}
manuallyStopAcquisitionIfNeeded( hDrv );
#ifdef USE_MV_DISPLAY_LIB
#endif
if( requestNr >= 0 )
{
}
{
}
return 0;
}
void captureLoop( CaptureParameter* pCaptureParams )
{
#ifdef _WIN32
HANDLE hThread = NULL;
unsigned int threadID = 0;
#endif
printf( "Press [ENTER] to end the continuous acquisition.\n" );
s_boTerminated = 0;
#ifdef _WIN32
hThread = ( HANDLE )_beginthreadex( 0, 0, liveLoop, ( LPVOID )( pCaptureParams ), 0, &threadID );
# ifdef __BORLANDC__
if( getch() == EOF )
{
printf( "Calling 'getch' did return EOF...\n" );
}
# else
if( _getch() == EOF )
{
printf( "Calling '_getch' did return EOF...\n" );
}
# endif
s_boTerminated = 1;
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread );
#else
liveLoop( pCaptureParams );
#endif
}
unsigned int isDeviceSupportedBySample( const HDEV hDev )
{
unsigned int dictValCount = 0;
unsigned int i = 0;
unsigned int result = 0;
int* dictVals = NULL;
HOBJ hPropInterfaceLayout = getDeviceProp( hDev, "InterfaceLayout" );
( getDeviceProp( hDev,
"AcquisitionStartStopBehaviour" ) ==
INVALID_ID ) )
{
return 0;
}
if( readTranslationDictValuesI( hPropInterfaceLayout, &dictVals, &dictValCount, 1 ) !=
PROPHANDLING_NO_ERROR )
{
return 0;
}
for( ; i < dictValCount; i++ )
{
{
result = 1;
break;
}
}
free( dictVals );
return result;
}
void setToMaxAOI( HOBJ hPropWidth, HOBJ hPropHeight )
{
if( isFeatureWriteable( hPropWidth ) )
{
setPropI64( hPropWidth, getPropI64( hPropWidth,
PROP_MAX_VAL ), 0 );
}
if( isFeatureWriteable( hPropHeight ) )
{
setPropI64( hPropHeight, getPropI64( hPropHeight,
PROP_MAX_VAL ), 0 );
}
}
void setToQuarterAOI( HOBJ hPropWidth, HOBJ hPropHeight )
{
if( isFeatureWriteable( hPropWidth ) )
{
setPropI64( hPropWidth, getPropI64( hPropWidth,
PROP_MAX_VAL ) / 2LL, 0 );
}
if( isFeatureWriteable( hPropHeight ) )
{
setPropI64( hPropHeight, getPropI64( hPropHeight,
PROP_MAX_VAL ) / 2LL, 0 );
}
}
int main( int argc, char* argv[] )
{
CaptureParameter captureParameter;
( void )argc;
( void )argv;
{
END_APPLICATION;
}
getDeviceFromUserInput( &hDevice, isDeviceSupportedBySample, 1 );
{
END_APPLICATION;
}
hPropHeight = getSettingProp( hDrv, "Base", "Height" );
hPropWidth = getSettingProp( hDrv, "Base", "Width" );
#ifdef USE_MV_DISPLAY_LIB
captureParameter.hDisp =
mvDispWindowCreate(
"ContinuousCaptureGenICam sample(plain 'C')" );
#endif
captureParameter.hDrv = hDrv;
setToQuarterAOI( hPropWidth, hPropHeight );
captureLoop( &captureParameter );
setToMaxAOI( hPropWidth, hPropHeight );
captureLoop( &captureParameter );
#ifdef USE_MV_DISPLAY_LIB
#endif
{
}
{
}
END_APPLICATION;
}
int iHeight
The height of the image in pixel or lines.
Definition mvImageBuffer.h:98
int iWidth
The width of the image in pixel.
Definition mvImageBuffer.h:100
TRequestResult result
The result of this request.
Definition mvDeviceManager.h:224
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.h:2601
@ dilGenICam
A GenICamâ„¢ like interface layout shall be used.
Definition mvDriverBaseEnums.h:2150
Fully describes a captured image.
Definition mvImageBuffer.h:94
Contains status information about the capture process.
Definition mvDeviceManager.h:218
MVDMR_API TDMR_ERROR DMR_CALL DMR_Close(void)
Frees internal data structures and decreases the usage counter for this library.
Definition mvDeviceManager.cpp:1265
MVDMR_API TDMR_ERROR DMR_CALL DMR_CloseDevice(HDRV hDrv, HDEV hDev)
Closes a device.
Definition mvDeviceManager.cpp:1585
MVDMR_API TDMR_ERROR DMR_CALL DMR_GetImageRequestBuffer(HDRV hDrv, int requestNr, ImageBuffer **ppBuffer)
Returns the ImageBuffer of the desired request.
Definition mvDeviceManager.cpp:3732
void MV_DISPLAY_API_CALL mvDispWindowDestroy(HDISP hDisp)
Closes a display window and frees allocated memory.
Definition mvDisplayWindow.cpp:315
TDisp *MV_DISPLAY_API_CALL mvDispWindowGetDisplayHandle(HDISP hDisp)
Returns a pointer to the internal object used for displaying the image data.
Definition mvDisplayWindow.cpp:353
HDISP MV_DISPLAY_API_CALL mvDispWindowCreate(const char *title)
Creates a new display window object.
Definition mvDisplayWindow.cpp:382
void MV_DISPLAY_API_CALL mvDispWindowShow(HDISP hDisp)
Shows the display window.
Definition mvDisplayWindow.cpp:436
void MV_DISPLAY_API_CALL mvDispSetImage(TDisp *pDisp, const void *pData, int width, int height, int bitsPerPixel, int pitch)
Sets the next image to display.
Definition mvDisplay.cpp:750
void MV_DISPLAY_API_CALL mvDispSetImageFromImageBuffer(TDisp *pDisp, const ImageBuffer *pBuf)
Sets the next image to display.
Definition mvDisplayExtensions.cpp:154
void MV_DISPLAY_API_CALL mvDispUpdate(TDisp *pDisp)
Immediately redraws the current image.
Definition mvDisplay.cpp:809
const int INVALID_ID
A constant to check for an invalid ID returned from the property handling module.
Definition mvPropHandlingDatatypes.h:62
const int PROP_MAX_VAL
The index value to query the maximum value defined for this property.
Definition mvPropHandlingDatatypes.h:66
MVDMR_API TPROPHANDLING_ERROR DMR_CALL OBJ_GetF(HOBJ hProp, double *pVal, int index)
Receives a property's value as a float value.
Definition ObjectHandling.cpp:2956
MVDMR_API TPROPHANDLING_ERROR DMR_CALL OBJ_GetI(HOBJ hProp, int *pVal, int index)
Receives a property's value as an integer value.
Definition ObjectHandling.cpp:2658
@ PROPHANDLING_NO_ERROR
The operation has been executed successfully.
Definition mvPropHandlingDatatypes.h:384