Skip to content

Commit 58d88e9

Browse files
committed
A go at making the depth_packet_stream_parser better.
Iterates through all bytes to find footer. Copy data in chunks. Doesn't use additional working buffer. Adds timestamp
1 parent 66d0e37 commit 58d88e9

File tree

6 files changed

+74
-105
lines changed

6 files changed

+74
-105
lines changed

examples/protonect/include/libfreenect2/depth_packet_processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace libfreenect2
4040
struct LIBFREENECT2_API DepthPacket
4141
{
4242
uint32_t sequence;
43+
uint32_t timestamp;
4344
unsigned char *buffer;
4445
size_t buffer_length;
4546
};

examples/protonect/include/libfreenect2/depth_packet_stream_parser.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,8 @@ class LIBFREENECT2_API DepthPacketStreamParser : public DataCallback
6464
libfreenect2::BaseDepthPacketProcessor *processor_;
6565

6666
libfreenect2::DoubleBuffer buffer_;
67-
libfreenect2::Buffer work_buffer_;
6867

69-
uint32_t current_sequence_;
70-
uint32_t current_subsequence_;
68+
uint32_t next_subsequence_;
7169
};
7270

7371
} /* namespace libfreenect2 */

examples/protonect/include/libfreenect2/frame_listener.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define FRAME_LISTENER_HPP_
2929

3030
#include <cstddef>
31+
#include <stdint.h>
3132
#include <libfreenect2/config.h>
3233

3334
namespace libfreenect2
@@ -42,6 +43,7 @@ struct LIBFREENECT2_API Frame
4243
Depth = 4
4344
};
4445

46+
uint32_t timestamp;
4547
size_t width, height, bytes_per_pixel;
4648
unsigned char* data;
4749

examples/protonect/src/cpu_depth_packet_processor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,9 @@ void CpuDepthPacketProcessor::process(const DepthPacket &packet)
741741

742742
impl_->startTiming();
743743

744+
impl_->ir_frame->timestamp = packet.timestamp;
745+
impl_->depth_frame->timestamp = packet.timestamp;
746+
744747
cv::Mat m = cv::Mat::zeros(424, 512, CV_32FC(9)), m_filtered = cv::Mat::zeros(424, 512, CV_32FC(9)), m_max_edge_test = cv::Mat::ones(424, 512, CV_8UC1);
745748

746749
float *m_ptr = m.ptr<float>();

examples/protonect/src/depth_packet_stream_parser.cpp

Lines changed: 61 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,14 @@ namespace libfreenect2
3333
{
3434

3535
DepthPacketStreamParser::DepthPacketStreamParser() :
36-
processor_(noopProcessor<DepthPacket>()),
37-
current_sequence_(0),
38-
current_subsequence_(0)
36+
processor_(noopProcessor<DepthPacket>()),
37+
next_subsequence_(0)
3938
{
40-
size_t single_image = 512*424*11/8;
39+
size_t single_image = 512 * 424 * 11 / 8;
4140

42-
buffer_.allocate((single_image) * 10);
43-
buffer_.front().length = buffer_.front().capacity;
44-
buffer_.back().length = buffer_.back().capacity;
45-
46-
work_buffer_.data = new unsigned char[single_image * 2];
47-
work_buffer_.capacity = single_image * 2;
48-
work_buffer_.length = 0;
41+
buffer_.allocate((single_image)* 10);
42+
buffer_.front().length = 0;
43+
buffer_.back().length = 0;
4944
}
5045

5146
DepthPacketStreamParser::~DepthPacketStreamParser()
@@ -59,122 +54,86 @@ void DepthPacketStreamParser::setPacketProcessor(libfreenect2::BaseDepthPacketPr
5954

6055
void DepthPacketStreamParser::onDataReceived(unsigned char* buffer, size_t in_length)
6156
{
62-
// TODO: simplify this crap (so code, such unreadable, wow ;)
63-
Buffer &wb = work_buffer_;
57+
if (in_length == 0)
58+
return;
6459

65-
size_t in_offset = 0;
60+
DepthSubPacketFooter *footer = 0;
6661

67-
while(in_offset < in_length)
68-
{
69-
unsigned char *ptr_in = buffer + in_offset, *ptr_out = wb.data + wb.length;
70-
DepthSubPacketFooter *footer = 0;
71-
bool footer_found = false;
62+
Buffer &fb = buffer_.front();
7263

73-
size_t max_length = std::min<size_t>(wb.capacity - wb.length, in_length - 8);
64+
for (size_t i = 0; i < in_length; i++)
65+
{
66+
footer = reinterpret_cast<DepthSubPacketFooter *>(&buffer[i]);
7467

75-
for(; in_offset < max_length; ++in_offset)
68+
if (footer->magic0 == 0x0 && footer->magic1 == 0x9 && footer->subsequence != 9)
7669
{
77-
footer = reinterpret_cast<DepthSubPacketFooter *>(ptr_in);
78-
79-
if(footer->magic0 == 0x0 && footer->magic1 == 0x9)
70+
if (next_subsequence_ == footer->subsequence)
8071
{
81-
footer_found = true;
82-
break;
72+
// last part of current subsequence so copy up to where footer is found.
73+
memcpy(&fb.data[fb.length], buffer, i);
74+
fb.length += i;
75+
next_subsequence_ = footer->subsequence + 1;
8376
}
84-
85-
*ptr_out = *ptr_in;
86-
++ptr_in;
87-
++ptr_out;
77+
else
78+
{
79+
// reset buffer if we get a sequence out of order.
80+
std::cerr << "[DepthPacketStreamParser::handleNewData] Subsequence out of order. Got: " << footer->subsequence << " expected: " << next_subsequence_ << std::endl;
81+
fb.length = 0;
82+
next_subsequence_ = 0;
83+
}
84+
return;
8885
}
86+
else if (footer->magic0 == 0x0 && footer->magic1 == 0x9 && footer->subsequence == 9)
87+
{
88+
// got the last subsequence so copy up to where footer is found
89+
next_subsequence_ = 0;
8990

90-
wb.length = ptr_out - wb.data;
91+
memcpy(&fb.data[fb.length], buffer, i);
92+
fb.length += i;
9193

92-
if(footer_found)
93-
{
94-
if((in_length - in_offset) < sizeof(DepthSubPacketFooter))
95-
{
96-
std::cerr << "[DepthPacketStreamParser::handleNewData] incomplete footer detected!" << std::endl;
97-
}
98-
else if(footer->length > wb.length)
99-
{
100-
std::cerr << "[DepthPacketStreamParser::handleNewData] image data too short!" << std::endl;
101-
}
102-
else
94+
// does the received amount of data match expected
95+
if (fb.length == fb.capacity)
10396
{
104-
if(current_sequence_ != footer->sequence)
97+
if (processor_->ready())
10598
{
106-
if(current_subsequence_ == 0x3ff)
107-
{
108-
if(processor_->ready())
109-
{
110-
buffer_.swap();
111-
112-
DepthPacket packet;
113-
packet.sequence = current_sequence_;
114-
packet.buffer = buffer_.back().data;
115-
packet.buffer_length = buffer_.back().length;
116-
117-
processor_->process(packet);
118-
}
119-
else
120-
{
121-
//std::cerr << "[DepthPacketStreamParser::handleNewData] skipping depth packet!" << std::endl;
122-
}
123-
}
124-
else
125-
{
126-
std::cerr << "[DepthPacketStreamParser::handleNewData] not all subsequences received " << current_subsequence_ << std::endl;
127-
}
128-
129-
current_sequence_ = footer->sequence;
130-
current_subsequence_ = 0;
131-
}
99+
buffer_.swap();
132100

133-
Buffer &fb = buffer_.front();
101+
DepthPacket packet;
102+
packet.sequence = footer->sequence;
103+
packet.timestamp = footer->timestamp;
104+
packet.buffer = buffer_.back().data;
105+
packet.buffer_length = buffer_.back().length;
134106

135-
// set the bit corresponding to the subsequence number to 1
136-
current_subsequence_ |= 1 << footer->subsequence;
107+
processor_->process(packet);
137108

138-
if(footer->subsequence * footer->length > fb.length)
139-
{
140-
std::cerr << "[DepthPacketStreamParser::handleNewData] front buffer too short! subsequence number is " << footer->subsequence << std::endl;
141109
}
142110
else
143111
{
144-
memcpy(fb.data + (footer->subsequence * footer->length), wb.data + (wb.length - footer->length), footer->length);
112+
std::cerr << "[DepthPacketStreamParser::handleNewData] skipping depth packet!" << std::endl;
145113
}
146-
}
147114

148-
// reset working buffer
149-
wb.length = 0;
150-
// skip header
151-
in_offset += sizeof(DepthSubPacketFooter);
152-
}
153-
else
154-
{
155-
if((wb.length + 8) >= wb.capacity)
156-
{
157-
std::cerr << "[DepthPacketStreamParser::handleNewData] working buffer full, resetting it!" << std::endl;
158-
wb.length = 0;
159-
ptr_out = wb.data;
115+
// if a complete packet is processed or skipped, reset buffer.
116+
fb.length = 0;
117+
return;
160118
}
161-
162-
// copy remaining 8 bytes
163-
if((in_length - in_offset) != 8)
164-
{
165-
std::cerr << "[DepthPacketStreamParser::handleNewData] remaining data should be 8 bytes, but is " << (in_length - in_offset) << std::endl;
166-
}
167-
168-
for(; in_offset < in_length; ++in_offset)
119+
else
169120
{
170-
*ptr_out = *ptr_in;
171-
++ptr_in;
172-
++ptr_out;
121+
// if data amount doesn't match, reset buffer.
122+
std::cerr << "[DepthPacketStreamParser::handleNewData] Depth packet not complete - resetting buffer" << std::endl;
123+
fb.length = 0;
124+
return;
173125
}
174-
175-
wb.length = ptr_out - wb.data;
176126
}
177127
}
128+
// copy data if space
129+
if (fb.length + in_length > fb.capacity)
130+
{
131+
std::cerr << "[DepthPacketStreamParser::handleNewData] Buffer full - reseting" << std::endl;
132+
fb.length = 0;
133+
}
134+
135+
memcpy(&fb.data[fb.length], buffer, in_length);
136+
fb.length += in_length;
178137
}
179138

180139
} /* namespace libfreenect2 */

examples/protonect/src/opengl_depth_packet_processor.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,12 @@ void OpenGLDepthPacketProcessor::process(const DepthPacket &packet)
932932
impl_->run(has_listener ? &ir : 0, has_listener ? &depth : 0);
933933

934934
if(impl_->do_debug) glfwSwapBuffers(impl_->opengl_context_ptr);
935+
if (ir != 0)
936+
ir->timestamp = packet.timestamp;
937+
if (depth != 0)
938+
depth->timestamp = packet.timestamp;
939+
940+
935941

936942
impl_->stopTiming();
937943

0 commit comments

Comments
 (0)