From a48b5c69abab420ab3b7107ebd24afd926bfee14 Mon Sep 17 00:00:00 2001 From: Sebastian <sebastian@baldr.asgard> Date: Sun, 20 Oct 2019 20:17:13 +0300 Subject: [PATCH] python module --- python/ftl/__init__.py | 1 + python/ftl/ftlstream.py | 125 +++++++++++++++++++++++++++++++++++ python/{ => ftl}/libde265.py | 0 python/ftlstream.py | 31 --------- 4 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 python/ftl/__init__.py create mode 100644 python/ftl/ftlstream.py rename python/{ => ftl}/libde265.py (100%) delete mode 100644 python/ftlstream.py diff --git a/python/ftl/__init__.py b/python/ftl/__init__.py new file mode 100644 index 000000000..963e374bd --- /dev/null +++ b/python/ftl/__init__.py @@ -0,0 +1 @@ +from . ftlstream import FTLStream \ No newline at end of file diff --git a/python/ftl/ftlstream.py b/python/ftl/ftlstream.py new file mode 100644 index 000000000..9869d50d5 --- /dev/null +++ b/python/ftl/ftlstream.py @@ -0,0 +1,125 @@ +import msgpack +from collections import namedtuple +from . libde265 import Decoder + +_packet = namedtuple("Packet", ["codec", "definition", "block_total", "block_number", "flags", "data"]) +_stream_packet = namedtuple("StreamPacket", ["timestamp", "streamID", "chanel_count", "channel"]) + +_definition_t = { + 0 : (), + 1 : (), + 2 : (1080, 1920), + 3 : (720, 1280), + 4 : (), + 5 : (), + 6 : (), + 7 : (), + 8 : () +} + +class FTLStream: + def __init__(self, file): + self._file = open(file, "br") + self._decoders = {} + self._frames = {} + + try: + magic = self._file.read(5) + if magic[:4] != bytearray(ord(c) for c in "FTLF"): + raise Exception("wrong magic") + + self._unpacker = msgpack.Unpacker(self._file, raw=True, use_list=False) + + except Exception as ex: + self._file.close() + raise ex + + self._packets_read = 0 + + def __del__(self): + self._file.close() + + def _read_next(self): + v1, v2 = self._unpacker.unpack() + return _stream_packet._make(v1), _packet._make(v2) + + def _update_calib(self, sp, p): + ''' Update calibration ''' + pass + + def _update_pose(self, sp, p): + ''' Update pose ''' + pass + + def _decode_frame_hevc(self, sp, p): + ''' Decode HEVC frame ''' + + k = (sp.streamID, sp.channel) + + if k not in self._decoders: + self._decoders[k] = Decoder(_definition_t[p.definition]) + + decoder = self._decoders[k] + decoder.push_data(p.data) + decoder.decode() + img = decoder.get_next_picture() + + if img is not None: + self._frames[k] = img + + def read(self): + ''' + Reads data for until the next timestamp. Returns False if there is no + more data to read, otherwise returns True. + ''' + if self._packets_read == 0: + self._sp, self._p = self._read_next() + self._packets_read += 1 + + self._frames = {} + + ts = self._sp.timestamp + ex = None + + while self._sp.timestamp == ts: + try: + if self._p.codec == 100: # JSON + NotImplementedError("json decoding not implemented") + + elif self._p.codec == 101: # CALIBRATION + self._update_calib(self._sp, self._p) + + elif self._p.codec == 102: # POSE + self._update_pose(self._sp, self._p) + + elif self._p.codec == 3: # HEVC + self._decode_frame_hevc(self._sp, self._p) + + else: + raise ValueError("unkowno codec %i" % p.codec) + + except Exception as e: + ex = e + + try: + self._sp, self._p = self._read_next() + self._packets_read += 1 + + except msgpack.OutOfData: + return False + + if ex is not None: + raise ex + + return True + + def get_frames(self): + ''' Returns all frames ''' + return self._frames + + def get_frame(self, source, channel): + k = (source, channel) + if k in self._frames: + return self._frames[k] + else: + return None diff --git a/python/libde265.py b/python/ftl/libde265.py similarity index 100% rename from python/libde265.py rename to python/ftl/libde265.py diff --git a/python/ftlstream.py b/python/ftlstream.py deleted file mode 100644 index ec0155133..000000000 --- a/python/ftlstream.py +++ /dev/null @@ -1,31 +0,0 @@ -import msgpack -from collections import namedtuple - -_packet = namedtuple("Packet", ["codec", "definition", "block_total", "block_number", "flags", "data"]) -_stream_packet = namedtuple("StreamPacket", ["timestamp", "streamID", "chanel_count", "channel"]) - -class FTLStream: - def __init__(self, file): - self._file = open(file, "br") - - try: - magic = self._file.read(5) - if magic[:4] != bytearray(ord(c) for c in "FTLF"): - raise Exception("wrong magic") - - self._unpacker = msgpack.Unpacker(self._file, raw=True, use_list=False) - - except Exception as ex: - self._file.close() - raise ex - - def __del__(self): - self._file.close() - - def read(self): - # TODO: Different methods for reading different types? - return self._read_next() - - def _read_next(self): - v1, v2 = self._unpacker.unpack() - return _stream_packet._make(v1), _packet._make(v2) \ No newline at end of file -- GitLab