/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2012 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : include/ICLIO/PylonUtils.h ** ** Module : ICLIO ** ** Authors: Viktor Richter ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** *********************************************************************/ #ifndef ICL_PYLON_UTILS_H #define ICL_PYLON_UTILS_H #include #include #include #include namespace icl { namespace pylon { /// Buffer, registered to the Pylon-drivers StreamGrabber \ingroup GIGE_G template class PylonGrabberBuffer { private: T *m_pBuffer; Pylon::StreamBufferHandle m_hBuffer; public: PylonGrabberBuffer(size_t size) : m_pBuffer(NULL) { m_pBuffer = new T[size]; if (!m_pBuffer) throw icl::ICLException("Not enough memory to allocate image buffer"); } ~PylonGrabberBuffer(){ if (m_pBuffer) delete[] m_pBuffer; } T* getBufferPointer(void) { return m_pBuffer; } Pylon::StreamBufferHandle getBufferHandle(void) { return m_hBuffer; } void setBufferHandle(Pylon::StreamBufferHandle hBuffer) { m_hBuffer = hBuffer; } }; /// A buffer holding image information and timestamp \ingroup GIGE_G template class TsBuffer { public: /// Buffer for image information T* m_Buffer; /// Buffer for image-timestamp uint64_t m_Timestamp; /// holdss the size of m_Buffer size_t m_Size; /// Constructor allocates required memory TsBuffer(size_t size) : m_Timestamp(0), m_Size(size){ m_Buffer = new T[m_Size]; if (!m_Buffer) throw icl::ICLException("Not enough memory to allocate image buffer"); } /// Frees allocated memory ~TsBuffer(){ if (m_Buffer){ delete[] m_Buffer; } } /// uses icl::copy to write buffer-data to m_Buffer /** * casts buffer to internal type and copies m_Size blocks * to m_Buffer. */ void copy(void* buffer){ T* tmp = (T*) buffer; icl::copy(tmp, tmp + m_Size, m_Buffer); } }; /// This is used for concurrent writing and reading of TsBuffers. /** This class holds three TsBuffers of which one is the currently read and the other two are alternately written to. **/ class ConcGrabberBuffer { public: /// Constructor creates and initializes resources. ConcGrabberBuffer(int bufferSize=0); /// Destructor frees allocated memory. ~ConcGrabberBuffer(); /// returns a pointer to the most recent actualized buffer. /** the buffer will then be marked and not overwritten till the **/ TsBuffer* getNextImage(); /// returns a pointer to the next write buffer /** sets the returned buffer as current write buffer and marks the old write buffer as new. **/ TsBuffer* getNextBuffer(); /// frees allocated memory and reinitializes Buffers to bufferSize. void reset(int bufferSize); private: /// internal Buffers which alternately are read and written. TsBuffer* m_Buffers[3]; /// the Mutex is used for concurrent reading and writing of the queue. Mutex m_Mutex; /// The buffer currently written to. int m_Write; /// The write buffer currently not written to. int m_Next; /// The buffer currently read from. int m_Read; /// tells whether a new buffer is available. bool m_Avail; }; /// Utility Structure \ingroup GIGE_G /** * This struct is used to initialize and terminate the pylon environment. * It intializes Pylon on creation and terminates it on destruction. * Uses a static counter to ensure initialization only on first and * termination on last call. */ struct PylonAutoEnv{ public: /// Initializes Pylon environment if not already done. PylonAutoEnv(); /// Terminates Pylon environment when (calls to term) == (calls to init). ~PylonAutoEnv(); /// Initializes the Pylon environment. /** @return whether Pylon::PylonInitialize() actually was called. */ static bool initPylonEnv(); /// terminates the Pylon environment. /** @return whether Pylon::PylontTerminate() actually was called. */ static bool termPylonEnv(); }; /// Utility Structure \ingroup GIGE_G /** * This struct is used to realize easy interruprion of Pylon grabbing * processes. */ struct Interruptable{ /// Virtual destructor virtual ~Interruptable() {} /// starts the acquisition virtual void acquisitionStart() = 0; /// stops the acquisition virtual void acquisitionStop() = 0; /// starts grabbing virtual void grabbingStart() = 0; /// stops grabbing virtual void grabbingStop() = 0; }; /// Utility Structure \ingroup GIGE_G /** * This struct is used to stop the acquisition and restart it * on destruction. It also locks the mutex lock so this can't be * created twice at the same time. */ struct AcquisitionInterruptor{ private: /// A pointer to the PylonGrabberImpl that is to be stopped. Interruptable* m_Interu; public: /// stops the acquisiton /** * @param i The Interruptable to stop. * @param mock Whether to mock the stopping. This can be used to * create 'shallow' AcquisitionInterruptors on conditions. */ AcquisitionInterruptor(Interruptable* i, bool mock=false); /// Starts acquisition if stopped before. ~AcquisitionInterruptor(); }; /// Utility Structure \ingroup GIGE_G /** * This struct is used to stop grabbing and restart it on destruction. * This should not be created while image acquisition is still active. */ struct GrabbingInterruptor{ private: /// A pointer to the Interruptable that needs to be stopped. Interruptable* m_Interu; public: /// Constructor calls grabbingStop(). /** * @param i The Interruptable to stop. * @param mock Whether to mock the stopping. This can be used to * create 'shallow' GrabbingInterruptors on conditions. */ GrabbingInterruptor(Interruptable* i, bool mock=false); /// Destructor calls grabbingStart(). ~GrabbingInterruptor(); }; /// Prints help-information to std::cout void printHelp(); /// Uses args to find demanded device Pylon::CDeviceInfo getDeviceFromArgs(std::string args) throw(ICLException); /// Uses args to find out which BufferChannel to use. int channelFromArgs(std::string args); /// Returns a list of available Pylon devices. /** @param filter if provided will be used to filter available devices */ Pylon::DeviceInfoList_t getPylonDeviceList(Pylon::DeviceInfoList_t* filter=NULL); } //namespace } //namespace #endif