Skip to content

Commit 2bcf020

Browse files
committed
support find_first_sensor_time
1 parent b1a0861 commit 2bcf020

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

include/event_camera_py/decoder.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,24 @@ class Decoder
6868
return (std::tuple<bool, uint64_t>({reachedTimeLimit, nextTime}));
6969
}
7070

71+
std::tuple<bool, uint64_t> find_first_sensor_time(pybind11::object msg)
72+
{
73+
auto decoder = initialize_decoder(
74+
get_attr<std::string>(msg, "encoding"), get_attr<uint32_t>(msg, "width"),
75+
get_attr<uint32_t>(msg, "height"));
76+
77+
pybind11::object eventsObj = get_attr<pybind11::object>(msg, "events");
78+
Py_buffer view;
79+
if (PyObject_GetBuffer(eventsObj.ptr(), &view, PyBUF_CONTIG_RO) != 0) {
80+
throw std::runtime_error("cannot convert events to byte buffer");
81+
}
82+
uint64_t firstTime{0};
83+
const bool foundTime = decoder->findFirstSensorTime(
84+
reinterpret_cast<const uint8_t *>(view.buf), view.len, &firstTime);
85+
PyBuffer_Release(&view);
86+
return (std::tuple<bool, uint64_t>({foundTime, firstTime}));
87+
}
88+
7189
void decode_bytes(
7290
const std::string & encoding, uint16_t width, uint16_t height, uint64_t timeBase,
7391
pybind11::bytes events)
@@ -125,6 +143,7 @@ class Decoder
125143
DecoderType * initialize_decoder(const std::string & encoding, uint32_t width, uint32_t height)
126144
{
127145
accumulator_.initialize(width, height);
146+
// this will only create a decoder on the first call, subsequently return instance
128147
auto decoder = decoderFactory_.getInstance(encoding, width, height);
129148
if (!decoder) {
130149
throw(std::runtime_error("no decoder for encoding " + encoding));

src/decoder.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ void declare_decoder(pybind11::module & m, std::string typestr)
9494
time following time limit (only valid if time limit has been reached!)
9595
:rtype: tuple[boolean, uint64_t]
9696
)pbdoc")
97+
.def("find_first_sensor_time", &MyDecoder::find_first_sensor_time, R"pbdoc(
98+
find_first_sensor_time(msg) -> tuple[Boolean, uint64_t]
99+
100+
Peeks into encoded message to find first event sensor time stamp. The
101+
boolean return flag indicates whether any time stamp was detected.
102+
This function does not advance the state of the decoder, and will not
103+
leverage state from previous message packets. It is typically used to cheaply find
104+
the first time stamp in an EventPacket message without decoding the whole packet.
105+
106+
:param msg: event packet message to decode
107+
:type msg: event_camera_msgs/msgs/EventPacket
108+
:return: tuple with flag (true if event sensor time was found) and the sensor time
109+
:rtype: tuple[boolean, uint64_t]
110+
)pbdoc")
97111
.def("get_start_time", &MyDecoder::get_start_time, R"pbdoc(
98112
get_start_time() -> uint64
99113

tests/test_1.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,20 @@ def test_unique_until(verbose=False):
182182
)
183183

184184

185+
def test_find_first_sensor_time(verbose=True):
186+
bag = BagReader('tests/test_events_1', verbose)
187+
if verbose:
188+
print('Testing find_first_time_stamp')
189+
decoder = Decoder()
190+
for _, msg, _ in bag.read_messages(topics=['/event_camera/events']):
191+
found_ts, ts = decoder.find_first_sensor_time(msg)
192+
assert found_ts
193+
if verbose:
194+
print('first sensor time stamp: ', ts)
195+
assert ts == 7139840
196+
break
197+
198+
185199
if __name__ == '__main__':
186200
test_decode_bytes(True)
187201
test_decode_msg(True)

0 commit comments

Comments
 (0)