Commit b0ad6b40 authored by Sebastien Petitdemange's avatar Sebastien Petitdemange
Browse files

First working version of hardware saving with Pilatus

parent 181c9dea
Subproject commit f62bc46bb4dbca5be759cc3901277e3521ca5bee Subproject commit a3434f09aaf3d1a623fe1e563b3100f7172bc4a4
...@@ -89,6 +89,8 @@ namespace lima { ...@@ -89,6 +89,8 @@ namespace lima {
void getDataFromHwFrameInfo(Data&,const HwFrameInfoType&, void getDataFromHwFrameInfo(Data&,const HwFrameInfoType&,
int readBlockLen=1); int readBlockLen=1);
static void transformHwFrameInfoToData(Data&,const HwFrameInfoType&,
int readBlockLen=1);
private: private:
class _DataDestroyCallback; class _DataDestroyCallback;
friend class _DataDestroyCallback; friend class _DataDestroyCallback;
......
...@@ -92,7 +92,6 @@ namespace lima { ...@@ -92,7 +92,6 @@ namespace lima {
FileFormat fileFormat; ///< the saving format (EDF,CBF...) FileFormat fileFormat; ///< the saving format (EDF,CBF...)
SavingMode savingMode; ///< saving mode (automatic,manual...) SavingMode savingMode; ///< saving mode (automatic,manual...)
OverwritePolicy overwritePolicy; ///< how you the saving react it find existing filename OverwritePolicy overwritePolicy; ///< how you the saving react it find existing filename
ManagedMode managedMode; ///< two option either harware (manage by SDK,hardware) or software (Lima core)
std::string indexFormat; ///< ie: %.4d if you want 4 digits std::string indexFormat; ///< ie: %.4d if you want 4 digits
long framesPerFile; ///< the number of images save in one files long framesPerFile; ///< the number of images save in one files
long nbframes; long nbframes;
...@@ -345,6 +344,8 @@ namespace lima { ...@@ -345,6 +344,8 @@ namespace lima {
bool m_has_hwsaving; bool m_has_hwsaving;
HwSavingCtrlObj* m_hwsaving; HwSavingCtrlObj* m_hwsaving;
_NewFrameSaveCBK* m_new_frame_save_cbk; _NewFrameSaveCBK* m_new_frame_save_cbk;
ManagedMode m_managed_mode; ///< two option either harware (manage by SDK,hardware) or software (Lima core)
std::string m_specific_hardware_format;
Stream& getStream(int stream_idx) Stream& getStream(int stream_idx)
{ bool stream_ok = (stream_idx >= 0) && (stream_idx < m_nb_stream); { bool stream_ok = (stream_idx >= 0) && (stream_idx < m_nb_stream);
...@@ -360,7 +361,7 @@ namespace lima { ...@@ -360,7 +361,7 @@ namespace lima {
{ return getStream(0).getParameters(Acq).savingMode; } { return getStream(0).getParameters(Acq).savingMode; }
ManagedMode getManagedMode() const ManagedMode getManagedMode() const
{ return getStream(0).getParameters(Acq).managedMode; } { return m_managed_mode; }
// --- from control // --- from control
void getSaveCounters(int& first_to_save, int& last_to_save) void getSaveCounters(int& first_to_save, int& last_to_save)
...@@ -390,6 +391,8 @@ namespace lima { ...@@ -390,6 +391,8 @@ namespace lima {
void _synchronousSaving(Data&,HeaderMap&); void _synchronousSaving(Data&,HeaderMap&);
bool _controlIsFault(); bool _controlIsFault();
bool _newFrameWrite(int); bool _newFrameWrite(int);
bool _checkHwFileFormat(const std::string&) const;
void _ReadImage(Data&,int framenb);
}; };
inline std::ostream& operator<<(std::ostream &os,const CtSaving::Parameters &params) inline std::ostream& operator<<(std::ostream &os,const CtSaving::Parameters &params)
......
...@@ -197,6 +197,8 @@ using namespace lima; ...@@ -197,6 +197,8 @@ using namespace lima;
void getFramePerFile(unsigned long& frames_per_file /Out/, void getFramePerFile(unsigned long& frames_per_file /Out/,
int stream_idx=0) const; int stream_idx=0) const;
void setManagedMode(ManagedMode mode);
void getManagedMode(ManagedMode &mode /Out/) const;
// --- common headers // --- common headers
void resetCommonHeader(); void resetCommonHeader();
......
...@@ -256,7 +256,7 @@ void CtBuffer::setup(CtControl *ct) ...@@ -256,7 +256,7 @@ void CtBuffer::setup(CtControl *ct)
m_hw_buffer_cb->releaseAll(); m_hw_buffer_cb->releaseAll();
} }
void CtBuffer::getDataFromHwFrameInfo(Data &fdata, void CtBuffer::transformHwFrameInfoToData(Data &fdata,
const HwFrameInfoType& frame_info, const HwFrameInfoType& frame_info,
int readBlockLen) int readBlockLen)
{ {
...@@ -302,12 +302,20 @@ void CtBuffer::getDataFromHwFrameInfo(Data &fdata, ...@@ -302,12 +302,20 @@ void CtBuffer::getDataFromHwFrameInfo(Data &fdata,
fdata.setBuffer(fbuf); fdata.setBuffer(fbuf);
fbuf->unref(); fbuf->unref();
}
void CtBuffer::getDataFromHwFrameInfo(Data &fdata,
const HwFrameInfoType& frame_info,
int readBlockLen)
{
DEB_MEMBER_FUNCT();
transformHwFrameInfoToData(fdata,frame_info,readBlockLen);
// Manage Buffer callback // Manage Buffer callback
if(m_hw_buffer_cb) if(m_hw_buffer_cb)
{ {
m_hw_buffer_cb->map(frame_info.frame_ptr); m_hw_buffer_cb->map(frame_info.frame_ptr);
fbuf->callback = m_data_destroy_callback; fdata.buffer->callback = m_data_destroy_callback;
} }
DEB_RETURN() << DEB_VAR1(fdata); DEB_RETURN() << DEB_VAR1(fdata);
} }
......
...@@ -244,6 +244,11 @@ void CtControl::prepareAcq() ...@@ -244,6 +244,11 @@ void CtControl::prepareAcq()
DEB_TRACE() << "Prepare Accumulation if needed"; DEB_TRACE() << "Prepare Accumulation if needed";
m_ct_accumulation->prepare(); m_ct_accumulation->prepare();
DEB_TRACE() << "Prepare Saving if needed";
m_ct_saving->_prepare();
m_autosave= m_ct_saving->hasAutoSaveMode();
m_ready= true;
DEB_TRACE() << "Prepare Hardware for Acquisition"; DEB_TRACE() << "Prepare Hardware for Acquisition";
m_hw->prepareAcq(); m_hw->prepareAcq();
...@@ -283,10 +288,6 @@ void CtControl::prepareAcq() ...@@ -283,10 +288,6 @@ void CtControl::prepareAcq()
else else
m_op_ext->setEndSinkTaskCallback(NULL); m_op_ext->setEndSinkTaskCallback(NULL);
m_ct_saving->_prepare();
m_autosave= m_ct_saving->hasAutoSaveMode();
m_ready= true;
#ifdef WITH_SPS_IMAGE #ifdef WITH_SPS_IMAGE
m_display_active_flag = m_ct_sps_image->isActive(); m_display_active_flag = m_ct_sps_image->isActive();
if(m_display_active_flag) if(m_display_active_flag)
...@@ -302,6 +303,19 @@ void CtControl::prepareAcq() ...@@ -302,6 +303,19 @@ void CtControl::prepareAcq()
m_images_buffer.clear(); m_images_buffer.clear();
m_ct_video->_prepareAcq(); m_ct_video->_prepareAcq();
m_ct_event->_prepareAcq(); m_ct_event->_prepareAcq();
//Check that no software operation is done if Hardware saving is activated
CtSaving::ManagedMode savingManagedMode;
m_ct_saving->getManagedMode(savingManagedMode);
if(savingManagedMode == CtSaving::Hardware &&
(m_op_int_active ||
m_op_ext_link_task_active ||
m_op_ext_sink_task_active ||
#ifdef WITH_SPS_IMAGE
m_display_active_flag ||
#endif
m_ct_video->isActive()))
THROW_CTL_ERROR(Error) << "Can't have any software operation if Hardware saving is active";
} }
void CtControl::startAcq() void CtControl::startAcq()
...@@ -472,7 +486,18 @@ void CtControl::ReadImage(Data &aReturnData,long frameNumber, ...@@ -472,7 +486,18 @@ void CtControl::ReadImage(Data &aReturnData,long frameNumber,
else else
{ {
aLock.unlock(); aLock.unlock();
ReadBaseImage(aReturnData,frameNumber,readBlockLen); // todo change when external op activated CtSaving::ManagedMode savingManagedMode;
m_ct_saving->getManagedMode(savingManagedMode);
if(savingManagedMode == CtSaving::Hardware)
{
if (readBlockLen != 1)
THROW_CTL_ERROR(NotSupported) << "Cannot read more than one frame "
<< "at a time with Hardware Saving";
m_ct_saving->_ReadImage(aReturnData,frameNumber);
}
else
ReadBaseImage(aReturnData,frameNumber,readBlockLen);
} }
DEB_RETURN() << DEB_VAR1(aReturnData); DEB_RETURN() << DEB_VAR1(aReturnData);
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "CtSaving.h" #include "CtSaving.h"
#include "CtSaving_Edf.h" #include "CtSaving_Edf.h"
#include "CtAcquisition.h" #include "CtAcquisition.h"
#include "CtBuffer.h"
#ifdef WITH_NXS_SAVING #ifdef WITH_NXS_SAVING
#include "CtSaving_Nxs.h" #include "CtSaving_Nxs.h"
...@@ -141,7 +142,7 @@ private: ...@@ -141,7 +142,7 @@ private:
*/ */
CtSaving::Parameters::Parameters() CtSaving::Parameters::Parameters()
: nextNumber(0), fileFormat(RAW), savingMode(Manual), : nextNumber(0), fileFormat(RAW), savingMode(Manual),
overwritePolicy(Abort),managedMode(Software), overwritePolicy(Abort),
indexFormat("%04d"),framesPerFile(1) indexFormat("%04d"),framesPerFile(1)
{ {
} }
...@@ -383,7 +384,7 @@ public: ...@@ -383,7 +384,7 @@ public:
m_saving(ct_saving) m_saving(ct_saving)
{ {
} }
bool newFrameWrite(int frame_id) bool newFrameWritten(int frame_id)
{ {
return m_saving._newFrameWrite(frame_id); return m_saving._newFrameWrite(frame_id);
} }
...@@ -398,7 +399,8 @@ CtSaving::CtSaving(CtControl &aCtrl) : ...@@ -398,7 +399,8 @@ CtSaving::CtSaving(CtControl &aCtrl) :
m_ready_flag(true), m_ready_flag(true),
m_need_compression(false), m_need_compression(false),
m_nb_save_cbk(0), m_nb_save_cbk(0),
m_end_cbk(NULL) m_end_cbk(NULL),
m_managed_mode(Software)
{ {
DEB_CONSTRUCTOR(); DEB_CONSTRUCTOR();
...@@ -610,6 +612,70 @@ void CtSaving::getFormat(FileFormat& format, int stream_idx) const ...@@ -610,6 +612,70 @@ void CtSaving::getFormat(FileFormat& format, int stream_idx) const
DEB_RETURN() << DEB_VAR1(format); DEB_RETURN() << DEB_VAR1(format);
} }
/** @brief return a list of hardware possible saving format
*/
void CtSaving::getHardwareFormatList(std::list<std::string> &format_list) const
{
DEB_MEMBER_FUNCT();
if(!m_has_hwsaving)
THROW_CTL_ERROR(NotSupported) << "No hardware saving for this camera";
m_hwsaving->getPossibleSaveFormat(format_list);
}
void CtSaving::setHardwareFormat(const std::string &format)
{
DEB_MEMBER_FUNCT();
if(!m_has_hwsaving)
THROW_CTL_ERROR(NotSupported) << "No hardware saving for this camera";
bool found = _checkHwFileFormat(format);
if(!found)
{
THROW_CTL_ERROR(NotSupported) <<
"Hardware does not support" << DEB_VAR1(format);
}
m_specific_hardware_format = format;
}
bool CtSaving::_checkHwFileFormat(const std::string &format) const
{
std::list<std::string> format_list;
m_hwsaving->getPossibleSaveFormat(format_list);
bool found = false;
for(std::list<std::string>::const_iterator i = format_list.begin();
!found && i != format_list.end();++i)
found = *i == format;
return found;
}
void CtSaving::_ReadImage(Data &image,int frameNumber)
{
DEB_MEMBER_FUNCT();
if(m_hwsaving->getCapabilities() & HwSavingCtrlObj::MANUAL_READ)
{
HwFrameInfoType frame;
m_hwsaving->readFrame(frame,frameNumber);
CtBuffer::transformHwFrameInfoToData(image,frame);
}
else
THROW_CTL_ERROR(NotSupported) << "Image read is not supported for this hardware";
}
void CtSaving::getHardwareFormat(std::string &format) const
{
DEB_MEMBER_FUNCT();
if(!m_has_hwsaving)
THROW_CTL_ERROR(NotSupported) << "No hardware saving for this camera";
format = m_specific_hardware_format;
}
/** @brief set the saving mode for a saving stream /** @brief set the saving mode for a saving stream
*/ */
void CtSaving::setSavingMode(SavingMode mode) void CtSaving::setSavingMode(SavingMode mode)
...@@ -709,13 +775,21 @@ void CtSaving::setManagedMode(CtSaving::ManagedMode mode) ...@@ -709,13 +775,21 @@ void CtSaving::setManagedMode(CtSaving::ManagedMode mode)
THROW_CTL_ERROR(InvalidValue) << DEB_VAR1(mode) << "Not supported"; THROW_CTL_ERROR(InvalidValue) << DEB_VAR1(mode) << "Not supported";
AutoMutex aLock(m_cond.mutex()); AutoMutex aLock(m_cond.mutex());
for (int s = 0; s < m_nb_stream; ++s) if(mode == Hardware)
{ {
Stream& stream = getStream(s); if(!m_has_hwsaving)
Parameters pars = stream.getParameters(Auto); THROW_CTL_ERROR(NotSupported) << "Hardware saving is not supported";
pars.managedMode = mode;
stream.setParameters(pars); int hw_cap = m_hwsaving->getCapabilities();
if(hw_cap & HwSavingCtrlObj::COMMON_HEADER)
m_hwsaving->setCommonHeader(m_common_header);
else if(!m_common_header.empty())
{
THROW_CTL_ERROR(Error) << "Hardware saving do not manage common header"
<< ", clear it first";
} }
}
m_managed_mode = mode;
} }
void CtSaving::getManagedMode(CtSaving::ManagedMode &mode) const void CtSaving::getManagedMode(CtSaving::ManagedMode &mode) const
...@@ -723,9 +797,7 @@ void CtSaving::getManagedMode(CtSaving::ManagedMode &mode) const ...@@ -723,9 +797,7 @@ void CtSaving::getManagedMode(CtSaving::ManagedMode &mode) const
DEB_MEMBER_FUNCT(); DEB_MEMBER_FUNCT();
AutoMutex aLock(m_cond.mutex()); AutoMutex aLock(m_cond.mutex());
const Stream& stream = getStream(0); mode = m_managed_mode;
const Parameters& pars = stream.getParameters(Auto);
mode = pars.managedMode;
} }
void CtSaving::_getTaskList(TaskType type, long frame_nr, void CtSaving::_getTaskList(TaskType type, long frame_nr,
...@@ -758,9 +830,7 @@ void CtSaving::resetCommonHeader() ...@@ -758,9 +830,7 @@ void CtSaving::resetCommonHeader()
AutoMutex aLock(m_cond.mutex()); AutoMutex aLock(m_cond.mutex());
ManagedMode managed_mode = getManagedMode(); ManagedMode managed_mode = getManagedMode();
if(managed_mode == Software) if(managed_mode == Hardware)
m_common_header.clear();
else
{ {
int hw_cap = m_hwsaving->getCapabilities(); int hw_cap = m_hwsaving->getCapabilities();
if(hw_cap & HwSavingCtrlObj::COMMON_HEADER) if(hw_cap & HwSavingCtrlObj::COMMON_HEADER)
...@@ -768,6 +838,7 @@ void CtSaving::resetCommonHeader() ...@@ -768,6 +838,7 @@ void CtSaving::resetCommonHeader()
else else
THROW_CTL_ERROR(NotSupported) << "Common header is not supported"; THROW_CTL_ERROR(NotSupported) << "Common header is not supported";
} }
m_common_header.clear();
} }
/** @brief set the common header. /** @brief set the common header.
This is the header which will be write for all frame for this acquisition This is the header which will be write for all frame for this acquisition
...@@ -779,9 +850,7 @@ void CtSaving::setCommonHeader(const HeaderMap &header) ...@@ -779,9 +850,7 @@ void CtSaving::setCommonHeader(const HeaderMap &header)
AutoMutex aLock(m_cond.mutex()); AutoMutex aLock(m_cond.mutex());
ManagedMode managed_mode = getManagedMode(); ManagedMode managed_mode = getManagedMode();
if(managed_mode == Software) if(managed_mode == Hardware)
m_common_header = header;
else
{ {
int hw_cap = m_hwsaving->getCapabilities(); int hw_cap = m_hwsaving->getCapabilities();
if(hw_cap & HwSavingCtrlObj::COMMON_HEADER) if(hw_cap & HwSavingCtrlObj::COMMON_HEADER)
...@@ -789,6 +858,7 @@ void CtSaving::setCommonHeader(const HeaderMap &header) ...@@ -789,6 +858,7 @@ void CtSaving::setCommonHeader(const HeaderMap &header)
else else
THROW_CTL_ERROR(NotSupported) << "Common header is not supported"; THROW_CTL_ERROR(NotSupported) << "Common header is not supported";
} }
m_common_header = header;
} }
/** @brief replace/add field in the common header /** @brief replace/add field in the common header
*/ */
...@@ -1394,7 +1464,8 @@ void CtSaving::_prepare() ...@@ -1394,7 +1464,8 @@ void CtSaving::_prepare()
DEB_TRACE() << "No auto save activated"; DEB_TRACE() << "No auto save activated";
AutoMutex aLock(m_cond.mutex()); AutoMutex aLock(m_cond.mutex());
if(m_managed_mode == Software)
{
m_need_compression = false; m_need_compression = false;
//prepare all the active streams //prepare all the active streams
...@@ -1409,6 +1480,42 @@ void CtSaving::_prepare() ...@@ -1409,6 +1480,42 @@ void CtSaving::_prepare()
m_nb_save_cbk = 0; m_nb_save_cbk = 0;
m_nb_compression_cbk.clear(); m_nb_compression_cbk.clear();
if(m_has_hwsaving)
{
m_hwsaving->stop();
m_hwsaving->setActive(false);
}
}
else
{
const Stream& stream = getStream(0);
Parameters params = stream.getParameters(Auto);
m_hwsaving->setDirectory(params.directory);
m_hwsaving->setPrefix(params.prefix);
m_hwsaving->setSuffix(params.suffix);
m_hwsaving->setNextNumber(params.nextNumber);
m_hwsaving->setIndexFormat(params.indexFormat);
std::string fileFormat;
switch(params.fileFormat)
{
case RAW: fileFormat = HwSavingCtrlObj::RAW_FORMAT_STR;break;
case EDF: fileFormat = HwSavingCtrlObj::EDF_FORMAT_STR;break;
case CBFFormat: fileFormat = HwSavingCtrlObj::CBF_FORMAT_STR;break;
case HARDWARE_SPECIFIC: fileFormat = m_specific_hardware_format;break;
default:
THROW_CTL_ERROR(NotSupported) << "Not supported yet";break;
}
if(!_checkHwFileFormat(fileFormat))
THROW_CTL_ERROR(NotSupported) << "Hardware doesn't support " << DEB_VAR1(fileFormat);
m_hwsaving->setSaveFormat(fileFormat);
m_hwsaving->setActive(true);
m_hwsaving->prepare();
m_hwsaving->start();
}
} }
CtSaving::SaveContainer::SaveContainer(Stream& stream) CtSaving::SaveContainer::SaveContainer(Stream& stream)
......
...@@ -26,7 +26,10 @@ ...@@ -26,7 +26,10 @@
#include <list> #include <list>
#include "LimaCompatibility.h" #include "LimaCompatibility.h"
#include "Debug.h" #include "Debug.h"
#include "HwFrameInfo.h"
#include "DirectoryEventUtils.h"
#ifdef __linux__
namespace lima namespace lima
{ {
class LIMACORE_API HwSavingCtrlObj class LIMACORE_API HwSavingCtrlObj
...@@ -35,46 +38,78 @@ namespace lima ...@@ -35,46 +38,78 @@ namespace lima
public: public:
typedef std::map<std::string,std::string> HeaderMap; typedef std::map<std::string,std::string> HeaderMap;
//Capabilities
static const int COMMON_HEADER = 0x1; ///< if support common header @see setCommonHeader static const int COMMON_HEADER = 0x1; ///< if support common header @see setCommonHeader
static const int MANUAL_WRITE = 0x2; ///< if support manual write @see writeFrame static const int MANUAL_WRITE = 0x2; ///< if support manual write @see writeFrame
static const int MANUAL_READ = 0x4; ///< if support manual read @see readFrame
//Basic Managed format
static const char *RAW_FORMAT_STR;
static const char *EDF_FORMAT_STR;
static const char *CBF_FORMAT_STR;
explicit HwSavingCtrlObj(int capabilities = 0); explicit HwSavingCtrlObj(int capabilities = 0);
virtual ~HwSavingCtrlObj(); virtual ~HwSavingCtrlObj();
virtual void setActive(bool) = 0; void setActive(bool);
virtual void setDirectory(const std::string&) = 0; bool isActive() const;
virtual void setPrefix(const std::string&) = 0;
virtual void setSuffix(const std::string&) = 0;
virtual void getSaveFormat(std::list<std::string> &format_list) const = 0; void setDirectory(const std::string&);
virtual void setSaveFormat(const std::string &format) = 0; void setPrefix(const std::string&);
void setSuffix(const std::string&);
void setNextNumber(long number);
void setIndexFormat(const std::string&);
void setSaveFormat(const std::string &format);
virtual void getPossibleSaveFormat(std::list<std::string> &format_list) const = 0;
int getCapabilities() const; int getCapabilities() const;
virtual void writeFrame(int frame_nr = -1,int nb_frames = 1); virtual void writeFrame(int frame_nr = -1,int nb_frames = 1);
virtual void readFrame(HwFrameInfoType&,int frame_nr);
virtual void setCommonHeader(const HeaderMap&); virtual void setCommonHeader(const HeaderMap&);
virtual void resetCommonHeader(); virtual void resetCommonHeader();
void prepare();
void start();
void stop();
class Callback class Callback
{ {
public: public:
virtual ~Callback() {} virtual ~Callback() {}
virtual bool newFrameWrite(int frame_id) = 0; virtual void prepare(const DirectoryEvent::Parameters &) {};
virtual bool newFrameWritten(int frame_id) = 0;
}; };
void registerCallback(Callback *cbk); void registerCallback(Callback *cbk);
void unregisterCallback(Callback *cbk); void unregisterCallback(Callback *cbk);
protected: protected:
/** @brief this methode should be call we a new frame is written virtual void _setActive(bool) {}
@param frame_id the frame id of the saved frame virtual void _prepare() {}
virtual void _start() {}
/** @brief return the full path of acquired image
*/ */
bool newFrameWrite(int frame_id); std::string _getFullPath(int image_number) const;
int m_caps; int m_caps;
bool m_active;
std::string m_directory;
std::string m_prefix;