gstreamer
Loading...
Searching...
No Matches
stream.cc
Go to the documentation of this file.
1// gstreamer
4
5// Implementation summary:
6// Build the packed frame record in memory before the header and payload are written out.
7
8bool GstreamerJSROFactory::startStreamImpl(const GFrameDataCollection* frameRunData) {
9 if (ofile == nullptr) { log->error(ERR_CANTOPENOUTPUT, "Error: can't open ", ofile); }
10
11 static constexpr int header_offset = sizeof(DataFrameHeader) / 4;
12 const GFrameHeader* header = frameRunData->getHeader();
13 long int frameID = header->getFrameID();
14 const std::vector<GIntegralPayload*>* intPayloadvec = frameRunData->getIntegralPayload();
15
16 // Reserve enough words for the packed binary header.
17 frame_data.resize(header_offset, 0);
18
19 // The first frame emits the SRO "super magic" words ahead of the normal records.
20 if (frameID == 1) {
21 std::vector<std::uint32_t> const super_magic = {0xC0DA2019, 0XC0DA0001};
22 ofile->write(reinterpret_cast<const char*>(super_magic.data()), sizeof(std::uint32_t) * 2);
23 }
24
25 // Populate the binary record header directly inside the word buffer.
26 DataFrameHeader& dataFrameHeader = *reinterpret_cast<DataFrameHeader*>(frame_data.data());
27
28 dataFrameHeader.source_id = 0;
29 dataFrameHeader.magic = 0xC0DA2019;
30 dataFrameHeader.format_version = 257;
31 dataFrameHeader.flags = 0;
32 dataFrameHeader.record_counter = llswap(frameID);
33 dataFrameHeader.ts_sec = llswap((frameID * 65536) / static_cast<int>(1e9));
34 dataFrameHeader.ts_nsec = llswap((frameID * 65536) % static_cast<int>(1e9));
35
36 // Build the payload words grouped by slot.
37 unsigned int crate = 0;
38 unsigned int slot, channel, charge, time;
39 unsigned int slots = 16;
40
41 frame_data.resize(header_offset);
42 frame_data.push_back(0x80000000);
43 frame_data.insert(frame_data.end(), slots, 0);
44
45 for (unsigned int i = 0; i < slots; ++i) {
46 int starting_point = (int)frame_data.size() - header_offset;
47 frame_data.push_back(0x80008000 | (crate << 8) | i);
48 int hit_counter = 0;
49
50 for (unsigned int hit = 0; hit < intPayloadvec->size(); ++hit) {
51 GIntegralPayload* intpayload = intPayloadvec->at(hit);
52 std::vector<int> payload = intpayload->getPayload();
53 crate = payload[0];
54 slot = payload[1];
55 channel = payload[2];
56 charge = payload[3];
57 time = payload[4];
58
59 if (i == slot) {
60 frame_data.push_back(charge | (channel << 13) | ((time / 4) << 17));
61 ++hit_counter;
62 }
63 }
64
65 // Empty slots remove the marker word entirely.
66 if (hit_counter == 0) {
67 frame_data.pop_back();
68 }
69 else {
70 ++hit_counter;
71 }
72
73 frame_data[header_offset + 1 + i] =
74 ((hit_counter) << 16) | starting_point;
75 }
76
77 // Finalize the size fields after payload assembly is complete.
78 DataFrameHeader& dfh = *reinterpret_cast<DataFrameHeader*>(frame_data.data());
79
80 dfh.payload_length = (uint32_t)frame_data.size() * sizeof(unsigned int) - sizeof(DataFrameHeader);
82 dfh.total_length = dfh.compressed_length + sizeof(DataFrameHeader) - 4;
83
84 return true;
85}
86
87
88bool GstreamerJSROFactory::endStreamImpl([[maybe_unused]] const GFrameDataCollection* frameRunData) {
89 if (ofile == nullptr) { log->error(ERR_CANTOPENOUTPUT, "Error: can't open ", ofile); }
90
91 return true;
92}
std::shared_ptr< GLogger > log
const GFrameHeader * getHeader() const
const std::vector< GIntegralPayload * > * getIntegralPayload() const
long int getFrameID() const
void error(int exit_code, Args &&... args) const
Shared constants and error codes for the gstreamer module.
#define ERR_CANTOPENOUTPUT
Output medium could not be opened successfully.
JLAB SRO binary frame streamer declarations.
Packed binary frame header written ahead of each JLAB SRO payload.
std::vector< int > getPayload() const