diff --git a/slsReceiverSoftware/include/DataStreamer.h b/slsReceiverSoftware/include/DataStreamer.h index 0bac8ee8c..4e584915e 100644 --- a/slsReceiverSoftware/include/DataStreamer.h +++ b/slsReceiverSoftware/include/DataStreamer.h @@ -22,10 +22,11 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { * Calls Base Class CreateThread(), sets ErrorMask if error and increments NumberofDataStreamers * @param f address of Fifo pointer * @param dr pointer to dynamic range - * @param freq poiner to streaming frequency - * @param timer poiner to timer if streaming frequency is random + * @param freq pointer to streaming frequency + * @param timer pointer to timer if streaming frequency is random + * @param sEnable pointer to short frame enable */ - DataStreamer(Fifo*& f, uint32_t* dr, uint32_t* freq, uint32_t* timer); + DataStreamer(Fifo*& f, uint32_t* dr, uint32_t* freq, uint32_t* timer, int* sEnable); /** * Destructor @@ -211,6 +212,9 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { /** Pointer to dynamic range */ uint32_t* dynamicRange; + /** Pointer to short frame enable */ + int* shortFrameEnable; + /** Pointer to Streaming frequency, if 0, sending random images with a timer */ uint32_t* streamingFrequency; @@ -240,5 +244,8 @@ class DataStreamer : private virtual slsReceiverDefs, public ThreadObject { /* File name to stream */ char fileNametoStream[MAX_STR_LENGTH]; + + /** Complete buffer used for roi, eg. shortGotthard */ + char* completeBuffer; }; diff --git a/slsReceiverSoftware/include/GeneralData.h b/slsReceiverSoftware/include/GeneralData.h index 11958b2b6..9b1153dce 100644 --- a/slsReceiverSoftware/include/GeneralData.h +++ b/slsReceiverSoftware/include/GeneralData.h @@ -69,6 +69,15 @@ public: /** Size of a header packet */ uint32_t headerPacketSize; + /** Streaming (for ROI - mainly short Gotthard) - Number of Pixels in x axis */ + uint32_t nPixelsX_Streamer; + + /** Streaming (for ROI - mainly short Gotthard) - Number of Pixels in y axis */ + uint32_t nPixelsY_Streamer; + + /** Streaming (for ROI - mainly short Gotthard) - Image size (in bytes) */ + uint32_t imageSize_Streamer; + /** Cosntructor */ GeneralData(): myDetectorType(slsReceiverDefs::GENERIC), @@ -88,7 +97,11 @@ public: fifoBufferHeaderSize(0), defaultFifoDepth(0), threadsPerReceiver(1), - headerPacketSize(0){}; + headerPacketSize(0), + nPixelsX_Streamer(0), + nPixelsY_Streamer(0), + imageSize_Streamer(0) + {}; /** Destructor */ virtual ~GeneralData(){}; @@ -124,8 +137,7 @@ public: subFrameNumber = -1; bunchId = -1; frameNumber = ((uint32_t)(*((uint32_t*)(packetData)))); - if (myDetectorType == slsReceiverDefs::PROPIX ||(myDetectorType == slsReceiverDefs::GOTTHARD && packetSize == GOTTHARD_PACKET_SIZE)) - frameNumber++; + frameNumber++; packetNumber = frameNumber&packetIndexMask; frameNumber = (frameNumber & frameIndexMask) >> frameIndexOffset; } @@ -170,8 +182,11 @@ public: "Fifo Buffer Header Size: %d\n" "Default Fifo Depth: %d\n" "Threads Per Receiver: %d\n" - "Header Packet Size: %d\n", - slsReceiverDefs::getDetectorType(myDetectorType).c_str(), + "Header Packet Size: %d\n" + "Streamer Pixels X: %d\n" + "Streamer Pixels Y: %d\n" + "Streamer Image Size: %d\n" + ,slsReceiverDefs::getDetectorType(myDetectorType).c_str(), nPixelsX, nPixelsY, headerSizeinPacket, @@ -188,7 +203,10 @@ public: fifoBufferHeaderSize, defaultFifoDepth, threadsPerReceiver, - headerPacketSize); + headerPacketSize, + nPixelsX_Streamer, + nPixelsY_Streamer, + imageSize_Streamer); }; }; @@ -214,6 +232,9 @@ class GotthardData : public GeneralData { fifoBufferSize = imageSize; fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + FILE_FRAME_HEADER_SIZE; defaultFifoDepth = 25000; + nPixelsX_Streamer = nPixelsX; + nPixelsY_Streamer = nPixelsY; + imageSize_Streamer = imageSize; }; }; @@ -237,7 +258,42 @@ class ShortGotthardData : public GeneralData { fifoBufferSize = imageSize; fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + FILE_FRAME_HEADER_SIZE; defaultFifoDepth = 25000; + nPixelsX_Streamer = 1280; + nPixelsY_Streamer = 1; + imageSize_Streamer = 1280 * 2; }; + + /** + * Get Header Infomation (frame number, packet number) + * @param index thread index for debugging purposes + * @param packetData pointer to data + * @param frameNumber frame number + * @param packetNumber packet number + */ + virtual void GetHeaderInfo(int index, char* packetData, uint64_t& frameNumber, uint32_t& packetNumber) const + { + frameNumber = ((uint32_t)(*((uint32_t*)(packetData)))); + packetNumber = 0; + } + + /** + * Get Header Infomation (frame number, packet number) + * @param index thread index for debugging purposes + * @param packetData pointer to data + * @param dynamicRange dynamic range to assign subframenumber if 32 bit mode + * @param frameNumber frame number + * @param packetNumber packet number + * @param subFrameNumber sub frame number if applicable + * @param bunchId bunch id + */ + virtual void GetHeaderInfo(int index, char* packetData, uint32_t dynamicRange, + uint64_t& frameNumber, uint32_t& packetNumber, uint32_t& subFrameNumber, uint64_t& bunchId) const + { + subFrameNumber = -1; + bunchId = -1; + frameNumber = ((uint32_t)(*((uint32_t*)(packetData)))); + packetNumber = 0; + } }; @@ -267,6 +323,9 @@ class PropixData : public GeneralData { fifoBufferSize = imageSize; fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + FILE_FRAME_HEADER_SIZE; defaultFifoDepth = 25000; + nPixelsX_Streamer = nPixelsX; + nPixelsY_Streamer = nPixelsY; + imageSize_Streamer = imageSize; }; }; @@ -295,6 +354,9 @@ class Moench02Data : public GeneralData { fifoBufferSize = imageSize; fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + FILE_FRAME_HEADER_SIZE; defaultFifoDepth = 2500; + nPixelsX_Streamer = nPixelsX; + nPixelsY_Streamer = nPixelsY; + imageSize_Streamer = imageSize; }; /** @@ -328,6 +390,9 @@ class Moench03Data : public GeneralData { fifoBufferSize = imageSize; fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + FILE_FRAME_HEADER_SIZE; defaultFifoDepth = 2500; + nPixelsX_Streamer = nPixelsX; + nPixelsY_Streamer = nPixelsY; + imageSize_Streamer = imageSize; }; }; @@ -353,6 +418,9 @@ class JCTBData : public GeneralData { fifoBufferSize = imageSize; fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + FILE_FRAME_HEADER_SIZE; defaultFifoDepth = 2500; + nPixelsX_Streamer = nPixelsX; + nPixelsY_Streamer = nPixelsY; + imageSize_Streamer = imageSize; }; /** @@ -397,6 +465,9 @@ private: fifoBufferSize = imageSize; fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + FILE_FRAME_HEADER_SIZE; defaultFifoDepth = 2500; + nPixelsX_Streamer = nPixelsX; + nPixelsY_Streamer = nPixelsY; + imageSize_Streamer = imageSize; }; /** @@ -487,6 +558,9 @@ private: footerOffset = headerSizeinPacket + dataSize; threadsPerReceiver = 2; headerPacketSize = 48; + nPixelsX_Streamer = nPixelsX; + nPixelsY_Streamer = nPixelsY; + imageSize_Streamer = imageSize; }; /** diff --git a/slsReceiverSoftware/src/DataStreamer.cpp b/slsReceiverSoftware/src/DataStreamer.cpp index 006d28fee..57dc4d097 100644 --- a/slsReceiverSoftware/src/DataStreamer.cpp +++ b/slsReceiverSoftware/src/DataStreamer.cpp @@ -37,12 +37,13 @@ const char* DataStreamer::jsonHeaderFormat = "\"fname\":\"%s\"}"; -DataStreamer::DataStreamer(Fifo*& f, uint32_t* dr, uint32_t* freq, uint32_t* timer) : +DataStreamer::DataStreamer(Fifo*& f, uint32_t* dr, uint32_t* freq, uint32_t* timer, int* sEnable) : ThreadObject(NumberofDataStreamers), generalData(0), fifo(f), zmqSocket(0), dynamicRange(dr), + shortFrameEnable(sEnable), streamingFrequency(freq), streamingTimerInMs(timer), currentFreqCount(0), @@ -50,7 +51,8 @@ DataStreamer::DataStreamer(Fifo*& f, uint32_t* dr, uint32_t* freq, uint32_t* tim acquisitionStartedFlag(false), measurementStartedFlag(false), firstAcquisitionIndex(0), - firstMeasurementIndex(0) + firstMeasurementIndex(0), + completeBuffer(0) { if(ThreadObject::CreateThread()){ pthread_mutex_lock(&Mutex); @@ -69,7 +71,8 @@ DataStreamer::DataStreamer(Fifo*& f, uint32_t* dr, uint32_t* freq, uint32_t* tim DataStreamer::~DataStreamer() { CloseZmqSocket(); - delete currentHeader; + if (currentHeader) delete currentHeader; + if (completeBuffer) delete completeBuffer; ThreadObject::DestroyThread(); NumberofDataStreamers--; } @@ -126,10 +129,17 @@ void DataStreamer::ResetParametersforNewMeasurement(char* fname){ firstMeasurementIndex = 0; measurementStartedFlag = false; strcpy(fileNametoStream, fname); + if (completeBuffer) { + delete completeBuffer; + completeBuffer = 0; + } + if (*shortFrameEnable >= 0) { + completeBuffer = new char[generalData->imageSize_Streamer]; + memset(completeBuffer, 0, generalData->imageSize_Streamer); + } CreateHeaderPart1(); } - void DataStreamer::CreateHeaderPart1() { char type[10] = ""; switch (*dynamicRange) { @@ -144,7 +154,7 @@ void DataStreamer::CreateHeaderPart1() { } sprintf(currentHeader, jsonHeaderFormat_part1, - STREAMER_VERSION, type, generalData->nPixelsX, generalData->nPixelsY); + STREAMER_VERSION, type, generalData->nPixelsX_Streamer, generalData->nPixelsY_Streamer); #ifdef VERBOSE cprintf(BLUE, "%d currentheader: %s\n", index, currentHeader); #endif @@ -276,9 +286,19 @@ void DataStreamer::ProcessAnImage(char* buf) { cprintf(RED,"Error: Could not send zmq header for fnum %lld and streamer %d\n", (long long int) fnum, index); - if (!zmqSocket->SendData(buf + FILE_FRAME_HEADER_SIZE, generalData->imageSize)) - cprintf(RED,"Error: Could not send zmq data for fnum %lld and streamer %d\n", - (long long int) fnum, index); + //shortframe gotthard - data sending + if (completeBuffer) { + memcpy(completeBuffer + ((generalData->imageSize)**shortFrameEnable), buf + FILE_FRAME_HEADER_SIZE, generalData->imageSize); + if (!zmqSocket->SendData(completeBuffer, generalData->imageSize_Streamer)) + cprintf(RED,"Error: Could not send zmq data for fnum %lld and streamer %d\n", + (long long int) fnum, index); + } + //normal - data sending + else { + if (!zmqSocket->SendData(buf + FILE_FRAME_HEADER_SIZE, generalData->imageSize)) + cprintf(RED,"Error: Could not send zmq data for fnum %lld and streamer %d\n", + (long long int) fnum, index); + } } diff --git a/slsReceiverSoftware/src/Listener.cpp b/slsReceiverSoftware/src/Listener.cpp index ba30bac0e..b52e9805d 100644 --- a/slsReceiverSoftware/src/Listener.cpp +++ b/slsReceiverSoftware/src/Listener.cpp @@ -330,10 +330,11 @@ uint32_t Listener::ListenToAnImage(char* buf) { } - //until last packet - while (pnum < (generalData->packetsPerFrame-1)) { + //until last packet isHeaderEmpty to account for gotthard short frame, else never entering this loop) + while ( isHeaderEmpty || (pnum < (generalData->packetsPerFrame-1))) { //listen to new packet + int curr_rc = udpSocket->ReceiveDataOnly(listeningPacket); if(curr_rc <= 0) { if (rc <= 0) return 0; //empty image diff --git a/slsReceiverSoftware/src/UDPStandardImplementation.cpp b/slsReceiverSoftware/src/UDPStandardImplementation.cpp index 104c723ce..0691de236 100644 --- a/slsReceiverSoftware/src/UDPStandardImplementation.cpp +++ b/slsReceiverSoftware/src/UDPStandardImplementation.cpp @@ -215,7 +215,7 @@ int UDPStandardImplementation::setDataStreamEnable(const bool enable) { if (enable) { bool error = false; for ( int i = 0; i < numThreads; ++i ) { - dataStreamer.push_back(new DataStreamer(fifo[i], &dynamicRange, &frameToGuiFrequency, &frameToGuiTimerinMS)); + dataStreamer.push_back(new DataStreamer(fifo[i], &dynamicRange, &frameToGuiFrequency, &frameToGuiTimerinMS, &shortFrameEnable)); dataStreamer[i]->SetGeneralData(generalData); if (dataStreamer[i]->CreateZmqSockets(&detID, &numThreads) == FAIL) { error = true;