With the first (uncommented by default) one, you can see the "real-time" processing which empties the request queue first. If you want to see the effect of queue underruns, you have to comment this line.
With the second (commented by default) one, you will see more output in the console window.
The sample empties the request queue using a do / while loop. The loop is running until the request number is not valid:
Afterwards the sample waits for results ...
... and finally when the request is ok (pRequest->isOK()
) it will display the latest process image:
#include <iostream>
#include <limits>
#include <memory>
#include <thread>
#include <apps/Common/exampleHelper.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_GenICam.h>
#ifdef _WIN32
# include <mvDisplay/Include/mvIMPACT_acquire_display.h>
# define USE_DISPLAY
# undef min
# undef max
#endif
#define DROP_OUTDATED_IMAGES
using namespace std;
static bool s_boTerminated = false;
struct ThreadParameter
{
#ifdef USE_DISPLAY
unique_ptr<ImageDisplayWindow> pDisplayWindow;
#endif
explicit ThreadParameter(
Device* p ) : pDev( p ) {}
ThreadParameter( const ThreadParameter& src ) = delete;
ThreadParameter& operator=( const ThreadParameter& rhs ) = delete;
};
class TimeStampProvider
{
private:
unsigned long long timestampTickFrequency_ = {1000000000};
mutable unique_ptr<PropertyI64> pTimestamp_;
unique_ptr<Method> pTimestampLatch_;
public:
explicit TimeStampProvider(
Device* pDev ) : pTimestamp_(), pTimestampLatch_()
{
if( dc.timestamp.isValid() )
{
pTimestamp_ = unique_ptr<PropertyI64>(
new PropertyI64( dc.timestamp.hObj() ) );
}
else if( dc.timestampLatchValue.isValid() )
{
pTimestamp_ = unique_ptr<PropertyI64>(
new PropertyI64( dc.timestampLatchValue.hObj() ) );
}
else if( tlc.gevTimestampValue.isValid() )
{
pTimestamp_ = unique_ptr<PropertyI64>(
new PropertyI64( tlc.gevTimestampValue.hObj() ) );
if( tlc.gevTimestampTickFrequency.isValid() )
{
timestampTickFrequency_ = tlc.gevTimestampTickFrequency.read();
}
}
if( dc.timestampLatch.isValid() )
{
pTimestampLatch_ = unique_ptr<Method>(
new Method( dc.timestampLatch.hObj() ) );
}
else if( tlc.gevTimestampControlLatch.isValid() )
{
pTimestampLatch_ = unique_ptr<Method>(
new Method( tlc.gevTimestampControlLatch.hObj() ) );
}
if( dc.timestampReset.isValid() )
{
dc.timestampReset.call();
}
else if( tlc.gevTimestampControlReset.isValid() )
{
tlc.gevTimestampControlReset.call();
}
}
unsigned long long getTimestamp_us( void ) const
{
if( pTimestamp_ && pTimestampLatch_ && (
static_cast<TDMR_ERROR>( pTimestampLatch_->call() ) == DMR_NO_ERROR ) )
{
const double t = static_cast<double>( pTimestamp_->read() ) / static_cast<double>( timestampTickFrequency_ );
return static_cast<unsigned long long>( t * 1000000 );
}
return numeric_limits<unsigned long long>::max();
}
};
void liveThread( ThreadParameter* pThreadParameter )
{
cout << "Initialising the device. This might take some time..." << endl;
try
{
pThreadParameter->pDev->open();
}
{
cout << "An error occurred while opening the device " << pThreadParameter->pDev->serial.read()
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return;
}
#ifdef USE_DISPLAY
ImageDisplay& display = pThreadParameter->pDisplayWindow->GetImageDisplay();
#endif
unique_ptr<TimeStampProvider> pTimestampProvider( ( pThreadParameter->pDev->interfaceLayout.read() == dilGenICam ) ? new TimeStampProvider( pThreadParameter->pDev ) : 0 );
while( ( result =
static_cast<TDMR_ERROR>( fi.imageRequestSingle() ) ) == DMR_NO_ERROR ) {};
#ifdef VERBOSE_OUTPUT
unsigned long long previousTimestamp = pTimestampProvider ? previousTimestamp = pTimestampProvider->getTimestamp_us() : 0;
#endif
if( result != DEV_NO_FREE_REQUEST_AVAILABLE )
{
cout << "'FunctionInterface.imageRequestSingle' returned with an unexpected result: " << result
<< "(" << ImpactAcquireException::getErrorCodeAsString( result ) << ")" << endl;
}
manuallyStartAcquisitionIfNeeded( pThreadParameter->pDev, fi );
Request* pPreviousRequest =
nullptr;
const unsigned int timeout_ms = {500};
unsigned int cnt = {0};
while( !s_boTerminated )
{
#ifdef DROP_OUTDATED_IMAGES
do
{
requestNr = fi.imageRequestWaitFor( 0 );
if( fi.isRequestNrValid( requestNr ) )
{
pRequest = fi.getRequest( requestNr );
# ifdef VERBOSE_OUTPUT
cout <<
"Unlocking outdated request: request_number=" << pRequest->
getNumber() <<
"." << endl;
# endif
#ifdef VERBOSE_OUTPUT
previousTimestamp = pTimestampProvider ? pTimestampProvider->getTimestamp_us() : pPreviousRequest->
infoTimeStamp_us.
read();
#endif
fi.imageRequestSingle();
pRequest = nullptr;
}
}
while( fi.isRequestNrValid( requestNr ) );
#endif
if( pRequest == nullptr )
{
#ifdef VERBOSE_OUTPUT
cout << "Waiting for a request to become ready:";
#endif
requestNr = fi.imageRequestWaitFor( timeout_ms );
pRequest = fi.isRequestNrValid( requestNr ) ? fi.getRequest( requestNr ) : nullptr;
}
#ifdef VERBOSE_OUTPUT
else
{
cout << "Processing already received request: ";
}
cout <<
" request_number=" << pRequest->
getNumber() <<
" and timestamp=" << pRequest->
infoTimeStamp_us.
read() <<
" and last_timestamp=" << previousTimestamp <<
" and difference=" << (
signed int )( pRequest->
infoTimeStamp_us.
read() - previousTimestamp ) <<
"usec." << endl;
#endif
if( pRequest != nullptr )
{
{
++cnt;
if( cnt % 100 == 0 )
{
cout << "Info from " << pThreadParameter->pDev->serial.read()
<< ": " << statistics.framesPerSecond.name() << ": " << statistics.framesPerSecond.readS()
<< ", " << statistics.errorCount.name() << ": " << statistics.errorCount.readS()
<< ", " << statistics.captureTime_s.name() << ": " << statistics.captureTime_s.readS() << endl;
}
#ifdef USE_DISPLAY
#endif
this_thread::sleep_for( chrono::milliseconds( 200 ) );
}
else
{
}
if( pPreviousRequest != nullptr )
{
}
pPreviousRequest = pRequest;
pRequest = nullptr;
#ifdef VERBOSE_OUTPUT
previousTimestamp = pTimestampProvider ? pTimestampProvider->getTimestamp_us() : pPreviousRequest->
infoTimeStamp_us.
read();
#endif
fi.imageRequestSingle();
}
}
manuallyStopAcquisitionIfNeeded( pThreadParameter->pDev, fi );
#ifdef USE_DISPLAY
#endif
if( pPreviousRequest != nullptr )
{
}
fi.imageRequestReset( 0, 0 );
}
int main( void )
{
Device* pDev = getDeviceFromUserInput( devMgr );
if( pDev == nullptr )
{
cout << "Unable to continue! Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
cout << "Press [ENTER] to end the application" << endl;
ThreadParameter threadParam( pDev );
#ifdef USE_DISPLAY
threadParam.pDisplayWindow = unique_ptr<ImageDisplayWindow>(
new ImageDisplayWindow(
"mvIMPACT_acquire sample, Device " + pDev->
serial.
read() ) );
#endif
thread myThread( liveThread, &threadParam );
cin.get();
s_boTerminated = true;
myThread.join();
return 0;
}
Grants access to devices that can be operated by this software interface.
Definition mvIMPACT_acquire.h:7171
This class and its functions represent an actual device detected by this interface in the current sys...
Definition mvIMPACT_acquire.h:6118
PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition mvIMPACT_acquire.h:6551
ZYX read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:4907
The function interface to devices supported by this interface.
Definition mvIMPACT_acquire.h:10758
Category for device information and control.
Definition mvIMPACT_acquire_GenICam.h:82
Category that contains the transport Layer control features.
Definition mvIMPACT_acquire_GenICam.h:13070
A base class for exceptions generated by Impact Acquire.
Definition mvIMPACT_acquire.h:256
std::string getErrorCodeAsString(void) const
Returns a string representation of the error associated with the exception.
Definition mvIMPACT_acquire.h:288
A class to call arbitrary driver functions.
Definition mvIMPACT_acquire.h:2779
std::string read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:5323
std::string readS(int index=0, const std::string &format="") const
Reads data from this property as a string.
Definition mvIMPACT_acquire.h:3340
Contains information about a captured buffer.
Definition mvIMPACT_acquire.h:8640
bool isOK(void) const
Convenience function to check if a request has been processed successfully.
Definition mvIMPACT_acquire.h:9474
PropertyIRequestResult requestResult
An enumerated integer property (read-only) defining the result of this request.
Definition mvIMPACT_acquire.h:9780
int unlock(void)
Unlocks the request for the driver again.
Definition mvIMPACT_acquire.h:9614
PropertyI64 infoTimeStamp_us
A 64 bit integer property (read-only) containing a timestamp to define the exact time this image has ...
Definition mvIMPACT_acquire.h:9913
int getNumber(void) const
Returns the number associated with this request.
Definition mvIMPACT_acquire.h:9060
Contains basic statistical information.
Definition mvIMPACT_acquire.h:14509
A class that can be used to display images in a window.
Definition mvIMPACT_acquire_display.h:606
A class that can be used for displaying images within existing windows or GUI elements that can provi...
Definition mvIMPACT_acquire_display.h:176
void RemoveImage(void)
Removes the current image from the display.
Definition mvIMPACT_acquire_display.h:395
void SetImage(const void *pData, int width, int height, int bitsPerPixel, int pitch)
Sets the next image to display.
Definition mvIMPACT_acquire_display.h:316
void Update(void) const
Immediately redraws the current image.
Definition mvIMPACT_acquire_display.h:405
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.h:2601
const int INVALID_ID
A constant to check for an invalid ID returned from the property handling module.
Definition mvPropHandlingDatatypes.h:62
@ DMR_NO_ERROR
The function call was executed successfully.
Definition mvDriverBaseEnums.h:2603
This namespace contains classes and functions that can be used to display images.
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition mvCommonDataTypes.h:34