Commit bca89ae3 authored by Samuel Debionne's avatar Samuel Debionne

Merge branch '5-manage-frame-error-for-b-w-camera-and-continuous-acq-frame' into 'master'

Resolve "Manage frame error for B/W camera and continuous acq frame"

Closes #5

See merge request !8
parents b9849245 3c03d5c0
Pipeline #9410 passed with stages
in 10 minutes and 12 seconds
......@@ -214,17 +214,20 @@ class BASLER_EXPORT Camera
void getTestImageSelector(TestImageSelector& set) const;
private:
enum BufferMode {TmpBuffer, SoftBuffer};
class _AcqThread;
friend class _AcqThread;
void _stopAcq(bool);
void _setStatus(Camera::Status status,bool force);
void _freeStreamGrabber();
void _allocColorBuffer();
void _initColorStreamGrabber();
void _allocTmpBuffer();
void _initStreamGrabber(BufferMode mode);
void _startAcq();
void _readTrigMode();
void _forceVideoMode(bool force);
static const int NB_COLOR_BUFFER = 2;
static const int NB_TMP_BUFFER = 2;
//- lima stuff
SoftBufferCtrlObj m_buffer_ctrl_obj;
int m_nb_frames;
......@@ -256,7 +259,7 @@ class BASLER_EXPORT Camera
int m_receive_priority;
bool m_color_flag;
bool m_video_flag_mode;
void* m_color_buffer[NB_COLOR_BUFFER];
void* m_tmp_buffer[NB_TMP_BUFFER];
VideoCtrlObj* m_video;
TrigMode m_trigger_mode;
};
......
......@@ -289,14 +289,12 @@ Camera::Camera(const std::string& camera_id,int packet_size,int receive_priority
// Error handling
THROW_HW_ERROR(Error) << e.GetDescription();
}
if(m_color_flag) {
_allocColorBuffer();
}
else
{
for(int i = 0;i < NB_COLOR_BUFFER;++i)
m_color_buffer[i] = NULL;
}
// if color camera video capability will be available
m_video_flag_mode = m_color_flag;
// alloc a temporary buffer used for live mode and color camera
_allocTmpBuffer();
}
//---------------------------
......@@ -319,12 +317,11 @@ Camera::~Camera()
DEB_TRACE() << "Close camera";
delete Camera_;
Camera_ = NULL;
if (m_video_flag_mode)
for(int i = 0;i < NB_COLOR_BUFFER;++i)
for(int i = 0;i < NB_TMP_BUFFER;++i)
#ifdef __unix
free(m_color_buffer[i]);
free(m_tmp_buffer[i]);
#else
_aligned_free(m_color_buffer[i]);
_aligned_free(m_tmp_buffer[i]);
#endif
}
catch (GenICam::GenericException &e)
......@@ -341,59 +338,17 @@ void Camera::prepareAcq()
try
{
if(!m_video_flag_mode) {
_freeStreamGrabber();
// Get the first stream grabber object of the selected camera
DEB_TRACE() << "Get the first stream grabber object of the selected camera";
StreamGrabber_ = new Camera_t::StreamGrabber_t(Camera_->GetStreamGrabber(0));
//Change priority to m_receive_priority
if(m_receive_priority > 0)
{
StreamGrabber_->ReceiveThreadPriorityOverride.SetValue(true);
StreamGrabber_->ReceiveThreadPriority.SetValue(m_receive_priority);
}
// Set Socket Buffer Size
DEB_TRACE() << "Set Socket Buffer Size";
if (m_socketBufferSize >0 )
{
StreamGrabber_->SocketBufferSize.SetValue(m_socketBufferSize);
}
// Open the stream grabber
DEB_TRACE() << "Open the stream grabber";
StreamGrabber_->Open();
if(!StreamGrabber_->IsOpen())
{
delete StreamGrabber_;
StreamGrabber_ = NULL;
THROW_HW_ERROR(Error) << "Unable to open the steam grabber!";
}
// We won't use image buffers greater than ImageSize
DEB_TRACE() << "We won't use image buffers greater than ImageSize";
StreamGrabber_->MaxBufferSize.SetValue((const size_t)ImageSize_);
StdBufferCbMgr& buffer_mgr = m_buffer_ctrl_obj.getBuffer();
// We won't queue more than c_nBuffers image buffers at a time
int nb_buffers;
buffer_mgr.getNbBuffers(nb_buffers);
DEB_TRACE() << "We'll queue " << nb_buffers << " image buffers";
StreamGrabber_->MaxNumBuffer.SetValue(nb_buffers);
// Allocate all resources for grabbing. Critical parameters like image
// size now must not be changed until FinishGrab() is called.
DEB_TRACE() << "Allocate all resources for grabbing, PrepareGrab";
StreamGrabber_->PrepareGrab();
// Put buffer into the grab queue for grabbing
DEB_TRACE() << "Put buffer into the grab queue for grabbing";
for(int i = 0;i < nb_buffers;++i)
{
void *ptr = buffer_mgr.getFrameBufferPtr(i);
// The registration returns a handle to be used for queuing the buffer.
StreamBufferHandle bufferId = StreamGrabber_->RegisterBuffer(ptr,(const size_t)ImageSize_);
StreamGrabber_->QueueBuffer(bufferId, NULL);
}
}
_freeStreamGrabber();
// For video (color camera or B/W forced to video) use a small 2-frames Tmp buffer
// to not stop acq if some frames are missing but just return the last acquired
// for other modes the SoftBuffer is filled by Pylon Grabber, and an frame error will
// stop the acquisition
if(m_video_flag_mode || m_nb_frames == 0)
_initStreamGrabber(TmpBuffer);
else
_initStreamGrabber(SoftBuffer);
if(m_trigger_mode == IntTrigMult)
_startAcq();
}
......@@ -436,9 +391,6 @@ void Camera::_startAcq()
{
DEB_MEMBER_FUNCT();
if(m_video_flag_mode)
_initColorStreamGrabber();
Camera_->AcquisitionStart.Execute();
//Start acqusition thread
......@@ -512,26 +464,52 @@ void Camera::_freeStreamGrabber()
StreamGrabber_ = NULL;
}
}
void Camera::_allocColorBuffer()
void Camera::_forceVideoMode(bool force)
{
DEB_MEMBER_FUNCT();
for(int i = 0;i < NB_COLOR_BUFFER;++i)
m_video_flag_mode = force;
}
void Camera::_allocTmpBuffer()
{
DEB_MEMBER_FUNCT();
for(int i = 0;i < NB_TMP_BUFFER;++i)
{
#ifdef __unix
posix_memalign(&m_color_buffer[i],16,ImageSize_);
int ret=posix_memalign(&m_tmp_buffer[i],16,ImageSize_);
if (ret)
THROW_HW_ERROR(Error) << "posix_memalign(): request for aligned memory allocation failed";
#else
m_color_buffer[i] = _aligned_malloc(ImageSize_,16);
m_tmp_buffer[i] = _aligned_malloc(ImageSize_,16);
if (m_tmp_buffer[i] == NULL)
THROW_HW_ERROR(Error) << "_aligned_malloc(): request for aligned memory allocation failed";
#endif
m_video_flag_mode = true;
}
}
void Camera::_initColorStreamGrabber()
void Camera::_initStreamGrabber(BufferMode mode)
{
DEB_MEMBER_FUNCT();
// Get the first stream grabber object of the selected camera
StreamGrabber_ = new Camera_t::StreamGrabber_t(Camera_->GetStreamGrabber(0));
DEB_TRACE() << "Get the first stream grabber object of the selected camera";
//Change priority to m_receive_priority
if(m_receive_priority > 0)
{
StreamGrabber_->ReceiveThreadPriorityOverride.SetValue(true);
StreamGrabber_->ReceiveThreadPriority.SetValue(m_receive_priority);
}
// Set Socket Buffer Size
DEB_TRACE() << "Set Socket Buffer Size";
if (m_socketBufferSize >0 )
{
StreamGrabber_->SocketBufferSize.SetValue(m_socketBufferSize);
}
// Open the stream grabber
DEB_TRACE() << "Open the stream grabber";
StreamGrabber_->Open();
if(!StreamGrabber_->IsOpen())
{
......@@ -539,15 +517,43 @@ void Camera::_initColorStreamGrabber()
StreamGrabber_ = NULL;
THROW_HW_ERROR(Error) << "Unable to open the steam grabber!";
}
// We won't use image buffers greater than ImageSize
DEB_TRACE() << "We won't use image buffers greater than ImageSize";
StreamGrabber_->MaxBufferSize.SetValue((const size_t)ImageSize_);
StreamGrabber_->MaxNumBuffer.SetValue(NB_COLOR_BUFFER);
StreamGrabber_->PrepareGrab();
for(int i = 0;i < NB_COLOR_BUFFER;++i)
// Allocate all resources for grabbing. Critical parameters like image
// size now must not be changed until FinishGrab() is called.
if (mode == TmpBuffer)
{
DEB_TRACE() << "We'll queue " << NB_TMP_BUFFER << " image buffers";
StreamGrabber_->MaxNumBuffer.SetValue(NB_TMP_BUFFER);
DEB_TRACE() << "Allocate all resources for grabbing, PrepareGrab";
StreamGrabber_->PrepareGrab();
for(int i = 0;i < NB_TMP_BUFFER;++i)
{
StreamBufferHandle bufferId = StreamGrabber_->RegisterBuffer(m_tmp_buffer[i],
(const size_t)ImageSize_);
StreamGrabber_->QueueBuffer(bufferId,NULL);
}
}
else // SoftBuffer
{
StreamBufferHandle bufferId = StreamGrabber_->RegisterBuffer(m_color_buffer[i],
(const size_t)ImageSize_);
StreamGrabber_->QueueBuffer(bufferId,NULL);
StdBufferCbMgr& buffer_mgr = m_buffer_ctrl_obj.getBuffer();
int nb_buffers;
buffer_mgr.getNbBuffers(nb_buffers);
DEB_TRACE() << "We'll queue " << nb_buffers << " image buffers";
StreamGrabber_->MaxNumBuffer.SetValue(nb_buffers);
DEB_TRACE() << "Allocate all resources for grabbing, PrepareGrab";
StreamGrabber_->PrepareGrab();
for(int i = 0;i < nb_buffers;++i)
{
void *ptr = buffer_mgr.getFrameBufferPtr(i);
StreamBufferHandle bufferId = StreamGrabber_->RegisterBuffer(ptr,
(const size_t)ImageSize_);
StreamGrabber_->QueueBuffer(bufferId,NULL);
}
}
}
......@@ -612,12 +618,18 @@ void Camera::_AcqThread::threadFunction()
{
int nb_buffers;
buffer_mgr.getNbBuffers(nb_buffers);
if (!m_cam.m_nb_frames ||
if (m_cam.m_nb_frames == 0 ||
m_cam.m_image_number < int(m_cam.m_nb_frames - nb_buffers))
m_cam.StreamGrabber_->QueueBuffer(Result.Handle(),NULL);
HwFrameInfoType frame_info;
frame_info.acq_frame_nb = m_cam.m_image_number;
// copy TmpBuffer frame to SoftBuffer frame room
if (m_cam.m_nb_frames == 0)
{
void *ptr = buffer_mgr.getFrameBufferPtr(m_cam.m_image_number);
memcpy(ptr, (void *)Result.Buffer(), m_cam.ImageSize_);
}
continueAcq = buffer_mgr.newFrameReady(frame_info);
DEB_TRACE() << DEB_VAR1(continueAcq);
}
......
......@@ -47,8 +47,8 @@ Interface::Interface(Camera& cam,bool force_video_mode) :
// for greyscale camera but for having true video interface
// with gain/autogain and other true video features available
// one can force here for video interface.
m_cam._allocColorBuffer();
m_cam._initColorStreamGrabber();
DEB_ALWAYS() << "Ok force video cap. for a B/W camera";
m_cam._forceVideoMode(true);
}
m_video = new VideoCtrlObj(cam);
}
......
......@@ -38,6 +38,7 @@ VideoCtrlObj::~VideoCtrlObj()
void VideoCtrlObj::getSupportedVideoMode(std::list<VideoMode>& aList) const
{
DEB_MEMBER_FUNCT();
struct _VideoMode
{
const char* stringMode;
......@@ -181,6 +182,7 @@ void VideoCtrlObj::setLive(bool flag)
if(flag)
{
m_cam.setNbFrames(0);
m_cam.prepareAcq();
m_cam.startAcq();
}
else
......
......@@ -137,6 +137,9 @@ class BaslerClass(PyTango.DeviceClass):
'packet_size':
[PyTango.DevLong,
"Network packet size (MTU)",8000],
'force_video_mode':
[PyTango.DevBoolean,
"For B/W camera force to color-video mode",False],
}
cmd_list = {
......@@ -191,7 +194,7 @@ _BaslerInterface = None
# directory for for details about network optimization.
def get_control(frame_transmission_delay = 0, inter_packet_delay = 0,
packet_size = 8000,**keys) :
packet_size = 8000,force_video_mode= 'false', **keys) :
global _BaslerCam
global _BaslerInterface
......@@ -210,12 +213,18 @@ def get_control(frame_transmission_delay = 0, inter_packet_delay = 0,
camera_id = 'uname://' + util.get_ds_inst_name()
print ("basler camera_id:", camera_id)
# all properties are passed as string from LimaCCDs device get_control helper
# so need to be converted to correct type
if force_video_mode == 'true':
force = True
else: force = False
if _BaslerCam is None:
_BaslerCam = BaslerAcq.Camera(camera_id, int(packet_size))
_BaslerCam.setInterPacketDelay(int(inter_packet_delay))
_BaslerCam.setFrameTransmissionDelay(int(frame_transmission_delay))
_BaslerInterface = BaslerAcq.Interface(_BaslerCam)
_BaslerInterface = BaslerAcq.Interface(_BaslerCam, force)
return Core.CtControl(_BaslerInterface)
def get_tango_specific_class_n_device():
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment