Commit 2c02df26 authored by Laurent Claustre's avatar Laurent Claustre

Now use the AT_ConvertBuffer() sdk utility for decoding and destriding the raw frames

parent 5e0596f5
......@@ -31,6 +31,7 @@
// Camera SDK headers :
#include <atcore.h>
#include <atutility.h>
// LImA headers :
#include "lima/HwMaxImageSizeCallback.h"
......@@ -76,15 +77,20 @@ namespace lima
enum A3_FanSpeed { Off=0, Low=1, On=2};
enum A3_PixelEncoding {Mono12=0, Mono12Packed = 1, Mono16=2, Mono32=3};
/*
// In the order of the menu, the status of the cooling unit :
enum A3_TemperatureStatus { Cooler_Off=0,
Stabilised = 1,
Cooling = 2,
Drift = 3,
Not_Stabilised = 4,
T_Fault = 5 };
*/
struct SdkFrameDim {
AT_64 width;
AT_64 height;
AT_64 stride;
double bytes_per_pixel;
AT_64 size;
A3_PixelEncoding encoding;
const AT_WC* input_encoding;
const AT_WC* output_encoding;
bool is_encoded;
bool is_strided;
};
int getHwBitDepth(int *bit_depth);
Camera(const std::string& bitflow_path, int camera_number=0);
~Camera();
......@@ -136,8 +142,6 @@ namespace lima
void getPixelSize(double& sizex, double& sizey);
void getSdkFrameDim(FrameDim &frame_dim);
void getStatus(Camera::Status& status);
// --- Acquisition interface
......@@ -161,7 +165,8 @@ namespace lima
void setBitDepth(A3_BitDepth iMode);
void getBitDepth(A3_BitDepth &oMode) const;
void getBitDepthString(std::string &oDepthString) const;
void getPxEncoding(std::string &oPxEncoding) const;
void getPxEncoding(A3_PixelEncoding &oPxEncoding) const;
void getPxEncodingString(std::string &oPxEncoding) const;
void setTriggerMode(A3_TriggerMode iMode);
void getTriggerMode(A3_TriggerMode &oMode) const;
void getTriggerModeString(std::string &oModeString) const;
......@@ -199,16 +204,15 @@ namespace lima
void getReadoutTime(double &o_time) const;
void getSerialNumber(std::string &o_sn) const;
int getPixelStride() const;
bool isDestrideNeeded() const {return m_destride_active;};
bool isDecodeNeeded() const {return m_decode_active;};
void getSdkFrameDim(SdkFrameDim &frame_dim,bool last);
HwBufferCtrlObj* getTempBufferCtrlObj();
protected:
virtual void setMaxImageSizeCallbackActive(bool cb_active);
private:
int getHwBitDepth(int *bit_depth);
void setDestrideActive(bool active);
// -- some internals :
// Stopping an acquisition, iForce : without waiting the end of frame buffer retrieval by m_acq_thread
void _stopAcq(bool iImmediate);
......@@ -261,7 +265,8 @@ namespace lima
// -- Members
// LIMA / Acquisition (thread) related :
_BufferCtrlObj* m_buffer_ctrl_obj;
SoftBufferCtrlObj* m_buffer_ctrl_obj;
SoftBufferCtrlObj* m_temp_buffer_ctrl_obj;
// Pure thread and signals :
_AcqThread* m_acq_thread; // The thread retieving frame buffers from the SDK
Cond m_cond; // Waiting condition for inter thread signaling
......@@ -297,14 +302,15 @@ namespace lima
A3_TriggerMode m_trig_mode;
bool m_cooler;
double m_temperature_sp;
bool m_temperature_control_available;
// std::map<TrigMode, int> m_trig_mode_maps;
std::map<int, std::string> m_andor3_error_maps;
static bool sAndorSDK3Initted;
bool m_maximage_size_cb_active;
bool m_destride_active;
bool m_decode_active;
bool m_maximage_size_cb_active;
Camera::SdkFrameDim m_sdk_frame_dim;
};
// Some inline utility functions; used all-over in Andor3 plugin :
......
......@@ -106,7 +106,7 @@ namespace Andor3
void setBitDepth(A3_BitDepth iMode /In/ );
void getBitDepth(A3_BitDepth &oMode /Out/ ) const;
void getBitDepthString(std::string &oDepthString /Out/ ) const;
void getPxEncoding(std::string &oPxEncoding /Out/ ) const;
void getPxEncodingString(std::string &oPxEncoding /Out/ ) const;
void setTriggerMode(A3_TriggerMode iMode /In/ );
void getTriggerMode(A3_TriggerMode &oMode /Out/ ) const;
void getTriggerModeString(std::string &oModeString /Out/ ) const;
......@@ -144,9 +144,6 @@ namespace Andor3
void getReadoutTime(double &o_time /Out/ ) const;
void getSerialNumber(std::string &o_sn /Out/ ) const;
int getPixelStride() const;
bool isDestrideNeeded() const;
bool isDecodeNeeded() const;
};
};
......
This diff is collapsed.
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2013
// Copyright (C) : 2009-2015
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
......@@ -35,83 +35,100 @@ class _ReconstructionTask : public LinkTask
{
DEB_CLASS_NAMESPC(DebModCameraCom, "_ReconstructionTask", "Andor3");
public:
_ReconstructionTask(): m_decode_active(false), m_destride_active(false) {}
_ReconstructionTask()
{
AT_InitialiseUtilityLibrary();
}
~_ReconstructionTask()
{
AT_FinaliseUtilityLibrary();
}
void setSdkFrameDim(Camera::SdkFrameDim& frame_dim){m_sdk_frame_dim = frame_dim;};
void setBuffer( HwBufferCtrlObj* buffer_ctrl_obj) {m_buffer_ctrl_obj= (SoftBufferCtrlObj *)buffer_ctrl_obj;};
virtual Data process(Data&);
void setDecodeActive(bool flag) {m_decode_active = flag;};
void setDestrideActive(bool flag){m_destride_active = flag;};
void setRoi(Roi& roi) {m_roi=roi;};
private:
bool m_decode_active;
bool m_destride_active;
Roi m_roi;
Camera::SdkFrameDim m_sdk_frame_dim;
SoftBufferCtrlObj* m_buffer_ctrl_obj;
};
Data _ReconstructionTask::process(Data& src)
{
DEB_MEMBER_FUNCT();
if (m_decode_active)
StdBufferCbMgr &the_buffer_mgr = m_buffer_ctrl_obj->getBuffer();
if (src.depth() != 2)
{
if (src.depth() != 2)
{
char ErrorBuff[1024];
snprintf(ErrorBuff,sizeof(ErrorBuff),
"_ReconstructionTask: can't decode data only for 12bit packed, 2 bytes and data depth is %d",
src.depth());
throw ProcessException(ErrorBuff);
}
// Mono12Packed encoding: 3 bytes for 2 pixels
// ----------------------------------------------------------------------------------
// |Bits 11:4 = Most Significant Bits (MSB) | Bits 3:0 = Least Significant Bits (LSB) |
// ----------------------------------------------------------------------------------
// In buffer memory (ImageBuffer)
// -----------------------------------------------
// | ImageBuffer+0 | Pixel A (MSB) |
// -----------------------------------------------
// | ImageBuffer+1 | Pixel B (LSB) | Pixel A (LSB) |
// -----------------------------------------------
// | ImageBuffer+2 | Pixel B (MSB) |
// -----------------------------------------------
// | ImageBuffer+3 | Pixel C (MSB) |
// -----------------------------------------------
// | ImageBuffer+4 | Pixel D (LSB) | Pixel C (LSB) |
// -----------------------------------------------
// | ImageBuffer+5 | Pixel D (MSB) |
// -----------------------------------------------
//
int nb_pixels = src.size()/src.depth();
// for this unpacking algorithm we seek memory from bottom to top address
// this is not super efficient but a choice to not use 2 buffer systems for memory copies.
// move to the latest pixel memory position
unsigned short* dst_data = (unsigned short*)src.data()+nb_pixels-1;
// move the packed ptr to the last byte as well
int coded_size = (int) (nb_pixels * 1.5);
unsigned char* coded_ptr = (unsigned char*) src.data() + coded_size;
char ErrorBuff[1024];
snprintf(ErrorBuff,sizeof(ErrorBuff),
"_ReconstructionTask: can't decode data only for 12bit packed, 2 bytes and data depth is %d",
src.depth());
throw ProcessException(ErrorBuff);
}
int frame_number = src.frameNumber;
void * dest_buffer_ptr = src.data();
void * src_buffer_ptr = the_buffer_mgr.getFrameBufferPtr(frame_number);
int res = AT_ConvertBuffer(static_cast<AT_U8*>(src_buffer_ptr),
static_cast<AT_U8*>(dest_buffer_ptr),
m_sdk_frame_dim.width,
m_sdk_frame_dim.height,
m_sdk_frame_dim.stride,
m_sdk_frame_dim.input_encoding,
m_sdk_frame_dim.output_encoding);
if (! res == AT_SUCCESS)
{
THROW_HW_ERROR(Error) << "Cannot convert buffer to Mono16";
unsigned short msb_byte1, msb_byte2, lsb_byte;
while (nb_pixels)
{
msb_byte2 = *(--coded_ptr); lsb_byte= *(--coded_ptr); msb_byte1 = *(--coded_ptr);
*dst_data = (msb_byte2 << 4) + (lsb_byte >> 4);
*(--dst_data) = (msb_byte1 << 4) + (lsb_byte & 0xF);
nb_pixels-=2;
--dst_data;
}
} // if (m_decode_active)
}
// Mono12Packed encoding: 3 bytes for 2 pixels
// ----------------------------------------------------------------------------------
// |Bits 11:4 = Most Significant Bits (MSB) | Bits 3:0 = Least Significant Bits (LSB) |
// ----------------------------------------------------------------------------------
// In buffer memory (ImageBuffer)
// -----------------------------------------------
// | ImageBuffer+0 | Pixel A (MSB) |
// -----------------------------------------------
// | ImageBuffer+1 | Pixel B (LSB) | Pixel A (LSB) |
// -----------------------------------------------
// | ImageBuffer+2 | Pixel B (MSB) |
// -----------------------------------------------
// | ImageBuffer+3 | Pixel C (MSB) |
// -----------------------------------------------
// | ImageBuffer+4 | Pixel D (LSB) | Pixel C (LSB) |
// -----------------------------------------------
// | ImageBuffer+5 | Pixel D (MSB) |
// -----------------------------------------------
//
/***
int nb_pixels = src.size()/src.depth();
// for this unpacking algorithm we seek memory from bottom to top address
// this is not super efficient but a choice to not use 2 buffer systems for memory copies.
// move to the latest pixel memory position
unsigned short* dst_data = (unsigned short*)src.data()+nb_pixels-1;
// move the packed ptr to the last byte as well
int coded_size = (int) (nb_pixels * 1.5);
unsigned char* coded_ptr = (unsigned char*) src.data() + coded_size;
if (m_destride_active)
unsigned short msb_byte1, msb_byte2, lsb_byte;
while (nb_pixels)
{
Tasks::SoftRoi roi_task;
Point top_left = m_roi.getTopLeft();
Point bottom_right = m_roi.getBottomRight();
roi_task.setRoi(top_left.x, bottom_right.x,top_left.y, bottom_right.y);
return roi_task.process(src);
msb_byte2 = *(--coded_ptr); lsb_byte= *(--coded_ptr); msb_byte1 = *(--coded_ptr);
*dst_data = (msb_byte2 << 4) + (lsb_byte >> 4);
*(--dst_data) = (msb_byte1 << 4) + (lsb_byte & 0xF);
nb_pixels-=2;
--dst_data;
}
else
return src;
***/
return src;
}
//-----------------------------------------------------
......@@ -138,10 +155,9 @@ ReconstructionCtrlObj::~ReconstructionCtrlObj()
void ReconstructionCtrlObj::prepareAcq()
{
DEB_MEMBER_FUNCT();
bool destride_needed = m_cam.isDestrideNeeded();
bool decode_needed = m_cam.isDecodeNeeded();
if (!destride_needed && ! decode_needed)
Camera::SdkFrameDim the_sdk_frame_dim;
m_cam.getSdkFrameDim(the_sdk_frame_dim, true);
if (!the_sdk_frame_dim.is_encoded && ! the_sdk_frame_dim.is_strided)
{
m_active = false;
reconstructionChange(NULL);
......@@ -149,15 +165,8 @@ void ReconstructionCtrlObj::prepareAcq()
else
{
m_active = true;
m_task->setDestrideActive(destride_needed);
if (destride_needed)
{
Size detector_size;
m_cam.getDetectorImageSize(detector_size);
Roi roi(0,0,detector_size.getWidth(),detector_size.getHeight());
m_task->setRoi(roi);
}
m_task->setDecodeActive(decode_needed);
m_task->setSdkFrameDim(the_sdk_frame_dim);
m_task->setBuffer(m_cam.getTempBufferCtrlObj());
reconstructionChange(m_task);
}
}
......
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