Commit 2467bd50 authored by ahoms's avatar ahoms
Browse files

* changed Frelon::Camera Roi protocol: setRoi accepts any Roi, getRoi

  returns the effective one, and checkRoi does both withouth hw changes
* finished implementation of Frelon::Camera trigger mode, expusure
  and latency times, nb of frames and start/stop
* added user FrameCallback to Espia::Acq; renamed AcqStatus -> Status
* implemented Espia::BufferMgr wich concat frames and callbacks
* added concat frames in buffer mgrs allocBuffers and getBufferPtr
* changed [un]registerCallback in HwFrameCallbackGen (and derived)
  to recieve a reference to the callback object instead of its pointer
* extended and moved GetDefMaxNbBuffers and ClearBuffer to MemUtils;
  buffer managers now have them as default implementation
* print HwFrameInfoType::frame_timestamp with microsecond resolution;
  added ostream << X/YBorder and Corner operators



git-svn-id: https://scm.blissgarden.org/svn/lima/trunk@81 45c4679d-1946-429d-baad-37912b19538b
parent 2ca6b9cd
......@@ -3,6 +3,7 @@
#include "EspiaDev.h"
#include "SizeUtils.h"
#include "HwFrameCallback.h"
namespace lima
{
......@@ -10,26 +11,26 @@ namespace lima
namespace Espia
{
class Acq
class Acq : public HwFrameCallbackGen
{
public:
Acq(Dev& dev);
~Acq();
typedef struct AcqStatus {
bool acq_started;
bool acq_running;
int acq_run_nb;
int last_acq_frame_nb;
} AcqStatusType;
typedef struct Status {
bool started;
bool running;
int run_nb;
int last_frame_nb;
} StatusType;
void bufferAlloc(const FrameDim& frame_dim, int& nb_buffers,
int buffer_frames);
void bufferAlloc(int& nb_buffers, int nb_buffer_frames,
const FrameDim& frame_dim);
void bufferFree();
void getFrameDim(FrameDim& frame_dim);
const FrameDim& getFrameDim();
void getNbBuffers(int& nb_buffers);
void getBufferFrames(int& buffer_frames);
void getNbBufferFrames(int& nb_buffer_frames);
void *getBufferFramePtr(int buffer_nb, int frame_nb = 0);
void *getAcqFramePtr(int acq_frame_nb);
......@@ -38,13 +39,20 @@ class Acq
void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames);
void startAcq();
void stopAcq();
void getAcqStatus(AcqStatusType& acq_status);
void start();
void stop();
void getStatus(StatusType& status);
void getStartTimestamp(Timestamp& start_ts);
protected:
virtual void setFrameCallbackActive(bool cb_active);
private:
enum FrameCallback {
Last, User,
};
bool hasVirtualBuffers();
int realBufferNb(int virt_buffer, int virt_frame);
int realFrameNb (int virt_buffer, int virt_frame);
......@@ -55,11 +63,13 @@ class Acq
HwFrameInfoType& virt_info);
void resetFrameInfo(struct img_frame_info& frame_info);
static int dispatchFrameCb(struct espia_cb_data *cb_data);
static int dispatchFrameCallback(struct espia_cb_data *cb_data);
void registerLastFrameCb();
void unregisterLastFrameCb();
void lastFrameCb(struct espia_cb_data *cb_data);
void enableFrameCallback(FrameCallback frame_cb);
void disableFrameCallback(FrameCallback frame_cb);
int& getFrameCallbackNb(FrameCallback frame_cb);
void lastFrameCallback(struct espia_cb_data *cb_data);
void userFrameCallback(struct espia_cb_data *cb_data);
AutoMutex acqLock();
......@@ -67,7 +77,7 @@ class Acq
FrameDim m_frame_dim;
int m_nb_buffers;
int m_buffer_frames;
int m_nb_buffer_frames;
int m_real_frame_factor;
int m_real_frame_size;
......@@ -76,6 +86,7 @@ class Acq
Timestamp m_start_ts;
struct img_frame_info m_last_frame_info;
int m_last_frame_cb_nr;
int m_user_frame_cb_nr;
};
inline bool Acq::hasVirtualBuffers()
......@@ -96,12 +107,12 @@ inline int Acq::realFrameNb (int virt_buffer, int virt_frame)
inline int Acq::virtBufferNb(int real_buffer, int real_frame)
{
return (real_buffer * m_real_frame_factor +
real_frame / m_buffer_frames);
real_frame / m_nb_buffer_frames);
}
inline int Acq::virtFrameNb (int real_buffer, int real_frame)
{
return real_frame % m_buffer_frames;
return real_frame % m_nb_buffer_frames;
}
inline void Acq::getStartTimestamp(Timestamp& start_ts)
......
#ifndef ESPIABUFFERMGR_H
#define ESPIABUFFERMGR_H
#include "HwBufferMgr.h"
#include "EspiaAcq.h"
namespace lima
{
namespace Espia
{
class BufferMgr : public BufferCbMgr
{
public:
BufferMgr(Acq& acq);
virtual ~BufferMgr();
virtual Cap getCap();
virtual int getMaxNbBuffers(const FrameDim& frame_dim);
virtual void allocBuffers(int nb_buffers, int concat_frames,
const FrameDim& frame_dim);
virtual const FrameDim& getFrameDim();
virtual void getNbBuffers(int& nb_buffers);
virtual void getNbConcatFrames(int& nb_concat_frames);
virtual void releaseBuffers();
virtual void *getBufferPtr(int buffer_nb, int concat_frame_nb = 0);
virtual void getFrameInfo(int acq_frame_nb, HwFrameInfoType& info);
virtual void setStartTimestamp(Timestamp start_ts);
virtual void getStartTimestamp(Timestamp& start_ts);
protected:
class FrameCallback : public HwFrameCallback
{
public:
FrameCallback(BufferMgr& buffer_mgr)
: m_buffer_mgr(buffer_mgr) {}
virtual bool newFrameReady(const HwFrameInfoType& frame_info)
{
return m_buffer_mgr.newFrameReady(frame_info);
}
protected:
BufferMgr& m_buffer_mgr;
};
virtual void setFrameCallbackActive(bool cb_active);
private:
Acq& m_acq;
FrameCallback m_frame_cb;
};
} // namespace Espia
} // namespace lima
#endif // ESPIABUFFERMGR_H
#include "EspiaAcq.h"
#include "MemUtils.h"
using namespace lima;
using namespace lima::Espia;
#define CHECK_CALL(ret) ESPIA_CHECK_CALL(ret)
......@@ -11,25 +12,25 @@ using namespace lima::Espia;
Acq::Acq(Dev& dev)
: m_dev(dev)
{
m_nb_buffers = m_buffer_frames = 0;
m_nb_buffers = m_nb_buffer_frames = 0;
m_real_frame_factor = m_real_frame_size = 0;
m_nb_frames = 0;
m_started = false;
resetFrameInfo(m_last_frame_info);
m_last_frame_cb_nr = Invalid;
m_last_frame_cb_nr = m_user_frame_cb_nr = Invalid;
registerLastFrameCb();
enableFrameCallback(Last);
}
Acq::~Acq()
{
bufferFree();
unregisterLastFrameCb();
disableFrameCallback(Last);
}
int Acq::dispatchFrameCb(struct espia_cb_data *cb_data)
int Acq::dispatchFrameCallback(struct espia_cb_data *cb_data)
{
Acq *espia = (Acq *) cb_data->data;
......@@ -37,7 +38,9 @@ int Acq::dispatchFrameCb(struct espia_cb_data *cb_data)
int& cb_nr = cb_data->cb_nr;
if (cb_nr == espia->m_last_frame_cb_nr)
method = &Acq::lastFrameCb;
method = &Acq::lastFrameCallback;
else if (cb_nr == espia->m_user_frame_cb_nr)
method = &Acq::userFrameCallback;
if (method) {
try {
......@@ -50,14 +53,15 @@ int Acq::dispatchFrameCb(struct espia_cb_data *cb_data)
return ESPIA_OK;
}
void Acq::registerLastFrameCb()
void Acq::enableFrameCallback(FrameCallback frame_cb)
{
if (m_last_frame_cb_nr != Invalid)
int& cb_nr = getFrameCallbackNb(frame_cb);
if (cb_nr != Invalid)
return;
struct espia_cb_data cb_data;
cb_data.type = ESPIA_CB_ACQ;
cb_data.cb = dispatchFrameCb;
cb_data.cb = dispatchFrameCallback;
cb_data.data = this;
cb_data.timeout = SCDXIPCI_BLOCK_FOREVER;
......@@ -67,18 +71,39 @@ void Acq::registerLastFrameCb()
req_finfo.round_count = ESPIA_ACQ_ANY;
req_finfo.acq_frame_nr = ESPIA_ACQ_EACH;
m_dev.registerCallback(cb_data, m_last_frame_cb_nr);
m_dev.registerCallback(cb_data, cb_nr);
}
void Acq::unregisterLastFrameCb()
void Acq::disableFrameCallback(FrameCallback frame_cb)
{
if (m_last_frame_cb_nr == Invalid)
int& cb_nr = getFrameCallbackNb(frame_cb);
if (cb_nr == Invalid)
return;
m_dev.unregisterCallback(m_last_frame_cb_nr);
m_dev.unregisterCallback(cb_nr);
}
void Acq::lastFrameCb(struct espia_cb_data *cb_data)
int& Acq::getFrameCallbackNb(FrameCallback frame_cb)
{
switch (frame_cb) {
case Last:
return m_last_frame_cb_nr;
case User:
return m_user_frame_cb_nr;
default:
throw LIMA_HW_EXC(InvalidValue, "Invalid frame cb type");
}
}
void Acq::setFrameCallbackActive(bool cb_active)
{
if (cb_active)
enableFrameCallback(User);
else
disableFrameCallback(User);
}
void Acq::lastFrameCallback(struct espia_cb_data *cb_data)
{
AutoMutex l = acqLock();
......@@ -87,21 +112,31 @@ void Acq::lastFrameCb(struct espia_cb_data *cb_data)
m_last_frame_info = cb_finfo;
}
void Acq::bufferAlloc(const FrameDim& frame_dim, int& nb_buffers,
int buffer_frames)
void Acq::userFrameCallback(struct espia_cb_data *cb_data)
{
struct img_frame_info& cb_finfo = cb_data->info.acq.cb_finfo;
HwFrameInfo hw_finfo;
if (!finished_espia_frame_info(&cb_finfo, cb_data->ret))
real2virtFrameInfo(cb_finfo, hw_finfo);
newFrameReady(hw_finfo);
}
void Acq::bufferAlloc(int& nb_buffers, int nb_buffer_frames,
const FrameDim& frame_dim)
{
if (!frame_dim.isValid() || (nb_buffers <= 0) || (buffer_frames <= 0))
if (!frame_dim.isValid() || (nb_buffers <= 0) ||
(nb_buffer_frames <= 0))
throw LIMA_HW_EXC(InvalidValue, "Invalid frame_dim, "
"nb_buffers and/or buffer_frames");
"nb_buffers and/or nb_buffer_frames");
if ((frame_dim == m_frame_dim) && (nb_buffers == m_nb_buffers) &&
(buffer_frames == m_buffer_frames))
(nb_buffer_frames == m_nb_buffer_frames))
return;
bufferFree();
int& virt_buffers = nb_buffers;
int& virt_frames = buffer_frames;
int& virt_frames = nb_buffer_frames;
int real_buffers = virt_buffers;
int real_frames = virt_frames;
......@@ -128,28 +163,28 @@ void Acq::bufferAlloc(const FrameDim& frame_dim, int& nb_buffers,
m_frame_dim = frame_dim;
m_nb_buffers = virt_buffers;
m_buffer_frames = virt_frames;
m_nb_buffer_frames = virt_frames;
m_real_frame_factor = frame_factor;
m_real_frame_size = real_frame_size;
}
void Acq::bufferFree()
{
if ((m_nb_buffers == 0) || (m_buffer_frames == 0))
if ((m_nb_buffers == 0) || (m_nb_buffer_frames == 0))
return;
stopAcq();
stop();
CHECK_CALL(espia_buffer_free(m_dev));
m_frame_dim = FrameDim();
m_nb_buffers = m_buffer_frames = 0;
m_nb_buffers = m_nb_buffer_frames = 0;
m_real_frame_factor = m_real_frame_size = 0;
}
void Acq::getFrameDim(FrameDim& frame_dim)
const FrameDim& Acq::getFrameDim()
{
frame_dim = m_frame_dim;
return m_frame_dim;
}
void Acq::getNbBuffers(int& nb_buffers)
......@@ -157,9 +192,9 @@ void Acq::getNbBuffers(int& nb_buffers)
nb_buffers = m_nb_buffers;
}
void Acq::getBufferFrames(int& buffer_frames)
void Acq::getNbBufferFrames(int& nb_buffer_frames)
{
buffer_frames = m_buffer_frames;
nb_buffer_frames = m_nb_buffer_frames;
}
void *Acq::getBufferFramePtr(int buffer_nb, int frame_nb)
......@@ -186,7 +221,13 @@ void Acq::getFrameInfo(int acq_frame_nb, HwFrameInfoType& info)
finfo.frame_nr = ESPIA_ACQ_ANY;
finfo.round_count = ESPIA_ACQ_ANY;
finfo.acq_frame_nr = acq_frame_nb;
CHECK_CALL(espia_get_frame(m_dev, &finfo, SCDXIPCI_NO_BLOCK));
int ret = espia_get_frame(m_dev, &finfo, SCDXIPCI_NO_BLOCK);
if (ret == SCDXIPCI_ERR_NOTREADY) {
info = HwFrameInfo();
return;
}
CHECK_CALL(ret);
real2virtFrameInfo(finfo, info);
}
......@@ -228,7 +269,7 @@ void Acq::getNbFrames(int& nb_frames)
nb_frames = m_nb_frames;
}
void Acq::startAcq()
void Acq::start()
{
AutoMutex l = acqLock();
......@@ -243,19 +284,21 @@ void Acq::startAcq()
m_started = true;
}
void Acq::stopAcq()
void Acq::stop()
{
AutoMutex l = acqLock();
if (!m_started)
return;
{
AutoMutex l = acqLock();
if (!m_started)
return;
}
CHECK_CALL(espia_stop_acq(m_dev));
AutoMutex l = acqLock();
m_started = false;
}
void Acq::getAcqStatus(AcqStatusType& acq_status)
void Acq::getStatus(StatusType& status)
{
AutoMutex l = acqLock();
......@@ -263,9 +306,9 @@ void Acq::getAcqStatus(AcqStatusType& acq_status)
int acq_running = espia_acq_active(m_dev, &acq_run_nb);
CHECK_CALL(acq_running);
acq_status.acq_started = m_started;
acq_status.acq_running = acq_running;
acq_status.acq_run_nb = acq_run_nb;
acq_status.last_acq_frame_nb = m_last_frame_info.acq_frame_nr;
status.started = m_started;
status.running = acq_running;
status.run_nb = acq_run_nb;
status.last_frame_nb = m_last_frame_info.acq_frame_nr;
}
#include "EspiaBufferMgr.h"
#include "MemUtils.h"
using namespace lima;
using namespace lima::Espia;
using namespace std;
BufferMgr::BufferMgr(Acq& acq)
: m_acq(acq), m_frame_cb(*this)
{
}
BufferMgr::~BufferMgr()
{
}
BufferMgr::Cap BufferMgr::getCap()
{
return Basic | Concat;
}
int BufferMgr::getMaxNbBuffers(const FrameDim& frame_dim)
{
return GetDefMaxNbBuffers(frame_dim);
}
void BufferMgr::allocBuffers(int nb_buffers, int concat_frames,
const FrameDim& frame_dim)
{
m_acq.bufferAlloc(nb_buffers, concat_frames, frame_dim);
}
const FrameDim& BufferMgr::getFrameDim()
{
return m_acq.getFrameDim();
}
void BufferMgr::getNbBuffers(int& nb_buffers)
{
m_acq.getNbBuffers(nb_buffers);
}
void BufferMgr::getNbConcatFrames(int& nb_concat_frames)
{
m_acq.getNbBufferFrames(nb_concat_frames);
}
void BufferMgr::releaseBuffers()
{
m_acq.bufferFree();
}
void *BufferMgr::getBufferPtr(int buffer_nb, int concat_frame_nb)
{
return m_acq.getBufferFramePtr(buffer_nb, concat_frame_nb);
}
void BufferMgr::getFrameInfo(int acq_frame_nb, HwFrameInfoType& info)
{
m_acq.getFrameInfo(acq_frame_nb, info);
}
void BufferMgr::setStartTimestamp(Timestamp start_ts)
{
}
void BufferMgr::getStartTimestamp(Timestamp& start_ts)
{
m_acq.getStartTimestamp(start_ts);
}
void BufferMgr::setFrameCallbackActive(bool cb_active)
{
if (cb_active)
m_acq.registerFrameCallback(m_frame_cb);
else
m_acq.unregisterFrameCallback(m_frame_cb);
}
espia-objs = EspiaBase.o EspiaDev.o EspiaAcq.o EspiaSerialLine.o
espia-objs = EspiaBase.o EspiaDev.o EspiaAcq.o EspiaSerialLine.o \
EspiaBufferMgr.o
include ../include/espia.inc
......
......@@ -83,6 +83,14 @@ enum RoiMode {
None, Slow, Fast, Kinetic,
};
enum TimeUnitFactor {
Milliseconds, Microseconds,
};
typedef std::map<TimeUnitFactor, double> TimeUnitFactorMapType;
extern TimeUnitFactorMapType TimeUnitFactorMap;
extern const FrameDim MaxFrameDim;
......
......@@ -44,9 +44,9 @@ class Camera
void setRoiMode(RoiMode roi_mode);
void getRoiMode(RoiMode& roi_mode);
void checkRoi(Roi& roi);
void setRoi(const Roi& roi);
void getRoi(Roi& roi);
void checkRoi(const Roi& set_roi, Roi& hw_roi);
void setRoi(const Roi& set_roi);
void getRoi(Roi& hw_roi);
void setTriggerMode(TrigMode trig_mode);
void getTriggerMode(TrigMode& trig_mode);
......@@ -60,6 +60,9 @@ class Camera
void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames);
void start();
void stop();
private:
static const double HorzBinSleepTime;
......@@ -89,10 +92,16 @@ class Camera
void getImageRoiOffset(const Roi& req_roi, const Roi& image_roi,
Point& roi_offset);
void checkRoiMode(const Roi& roi);
void processRoiReq(Roi& roi, Roi& chan_roi, Point& roi_offset);
void processSetRoi(const Roi& req_roi, Roi& hw_roi, Roi& chan_roi,
Point& roi_offset);
void setTimeUnitFactor(TimeUnitFactor time_unit_factor);
void getTimeUnitFactor(TimeUnitFactor& time_unit_factor);
SerialLine m_ser_line;
Point m_roi_offset;
TrigMode m_trig_mode;
int m_nb_frames;
};
inline bool Camera::isChanActive(InputChan chan)
......
......@@ -102,4 +102,15 @@ FTMInputChanListMapType
lima::Frelon::FTMInputChanListMap(C_LIST_ITERS(FTMInputChanListCList));
typedef pair<TimeUnitFactor, double> FactorPair;
static const FactorPair TimeUnitFactorCList[] = {
FactorPair(Milliseconds, 1e-3),
FactorPair(Microseconds, 1e-6),
};
TimeUnitFactorMapType
lima::Frelon::TimeUnitFactorMap(C_LIST_ITERS(TimeUnitFactorCList));
const FrameDim lima::Frelon::MaxFrameDim(2048, 2048, Bpp16);
#include "FrelonCamera.h"
#include "RegEx.h"
#include "MiscUtils.h"
#include <sstream>
using namespace lima::Frelon;
......@@ -10,7 +11,8 @@ const double Camera::HorzBinSleepTime = 2;
Camera::Camera(Espia::SerialLine& espia_ser_line)
: m_ser_line(espia_ser_line)
{