diff --git a/core-buffer/include/formats.hpp b/core-buffer/include/formats.hpp index cb32b96..65ce12b 100644 --- a/core-buffer/include/formats.hpp +++ b/core-buffer/include/formats.hpp @@ -40,6 +40,16 @@ struct BufferBinaryFormat { }; #pragma pack(pop) + +struct ImageBinaryFormat { + ImageMetadata meta; + std::vector data; + ImageBinaryFormat(size_t H, size_t W, size_t D): data(H*W*D, 0) {}; + size_t size(){ return data.size(); } + char* data(){ return data.data(); } +}; + + #pragma pack(push) #pragma pack(1) struct BufferBinaryBlock diff --git a/jfj-combined/include/JfjFrameCache.hpp b/jfj-combined/include/JfjFrameCache.hpp index 99c4009..7471233 100644 --- a/jfj-combined/include/JfjFrameCache.hpp +++ b/jfj-combined/include/JfjFrameCache.hpp @@ -16,24 +16,26 @@ /** Frame cache - Reimplemented RamBuffer for the better handling of image assembly and concurrency. + Reimplemented RamBuffer for better concurrency. The class operates on in-memory arrays via pointer/reference access. It uses a linearly increasing pulseID index to provide some headroom for collecting frames from multiple detectors. **/ class FrameCache{ public: - FrameCache(uint64_t capacity, uint64_t line_size, uint64_t block_size, std::function*)> callback): - m_capacity(capacity), m_linesize(line_size), m_blocksize(block_size), f_send(callback), - m_vlock(capacity), m_valid(capacity), m_fill(capacity), m_meta(capacity), m_data(capacity) { - // Reserve the data buffer - for(auto& it: m_data){ it.resize(m_linesize*m_blocksize); } + FrameCache(uint64_t _C, uint64_t _MX, uint64_t _MY, uint64_t _D, std::function callback): + m_CAP(_C), m_MX(_MX), m_MY(_MY), m_M(_MX*_MY), m_PX(1024*_MX), m_PY(512*_MY), m_D(_D), + m_buffer(_C, ImageBinaryFormat(512*_MY, 1024*_MX, 2)), + f_send(callback), m_vlock(_C), m_valid(_C), m_fill(_C, 0) { }; - /** Emplace a specific frame and module **/ - void emplace(uint64_t pulseID, uint64_t moduleID, BufferBinaryFormat& ref_frame){ - uint64_t idx = pulseID % m_capacity; + /** Emplace + + Place a recorded frame to it's corresponding module location. + This simultaneously handles buffering and assembly. **/ + void emplace(uint64_t pulseID, uint64_t moduleIDX, BufferBinaryFormat& ref_frame){ + uint64_t idx = pulseID % m_CAP; // Wait for unlocking block while(m_vlock[idx]){ std::this_thread::yield(); } @@ -42,20 +44,19 @@ public: if(m_valid[idx]){ start_line(idx, ref_frame.meta); } // A new frame is starting - if(ref_frame.meta.frame_index != m_meta[idx].frame_index){ + if(ref_frame.meta.frame_index != m_buffer[idx].meta.frame_index){ flush_line(idx); start_line(idx, ref_frame.meta); } m_fill[idx]++; - char* ptr_dest = m_data[idx].data() + moduleID * m_blocksize; + char* ptr_dest = m_buffer[idx].data() + moduleIDX * m_blocksize; std::memcpy(ptr_dest, (void*)&ref_frame.data, m_blocksize); - std::memcpy(&m_meta[idx], (void*)&ref_frame.meta, sizeof(ModuleFrame)); + std::memcpy(&m_buffer[idx].meta, (void*)&ref_frame.meta, sizeof(ModuleFrame)); } - void flush_all(){ - for(int64_t idx=0; idx< m_capacity; idx++){ + for(int64_t idx=0; idx< m_CAP; idx++){ flush_line(idx); } } @@ -84,17 +85,20 @@ public: } private: - const uint64_t m_capacity; - const uint64_t m_linesize; - const uint64_t m_blocksize; + const uint64_t m_CAP; + const uint64_t m_MX; + const uint64_t m_MY; + const uint64_t m_M; + const uint64_t m_H; + const uint64_t m_W; + const uint64_t m_D; std::function*)> f_send; /** Main container and mutex guard **/ std::vector> m_vlock; std::vector> m_valid; std::vector> m_fill; - std::vector m_meta; - std::vector> m_data; + std::vector m_buffer; }; #endif // FRAME_CACHE_HPP diff --git a/jfj-combined/src/main.cpp b/jfj-combined/src/main.cpp index 891ea83..e8c7f78 100644 --- a/jfj-combined/src/main.cpp +++ b/jfj-combined/src/main.cpp @@ -7,8 +7,8 @@ #include "../include/JfjFrameWorker.hpp" -void dummy_sender(ImageMetadata* meta, std::vector* data){ - std::cout << "Sending " << meta->frame_index << std::endl; +void dummy_sender(ImageBinaryFormat& image){ + std::cout << "Sending " << image.meta.frame_index << std::endl; }