From 85a07a96e0b1f711ae9e766fcb8639b0eaab65ff Mon Sep 17 00:00:00 2001
From: Sebastian Hahta <joseha@utu.fi>
Date: Sat, 14 Dec 2019 12:17:10 +0200
Subject: [PATCH] python: msgpack calibration (read support)

---
 .../codecs/include/ftl/codecs/bitrates.hpp    |  4 +-
 python/ftl/ftlstream.py                       | 50 ++++++++++---------
 python/ftl/ftltypes.py                        |  5 +-
 3 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/components/codecs/include/ftl/codecs/bitrates.hpp b/components/codecs/include/ftl/codecs/bitrates.hpp
index fbacb4979..eeb857c82 100644
--- a/components/codecs/include/ftl/codecs/bitrates.hpp
+++ b/components/codecs/include/ftl/codecs/bitrates.hpp
@@ -13,8 +13,8 @@ namespace codecs {
 enum struct codec_t : uint8_t {
 	JPG = 0,
 	PNG,
-    H264,
-    HEVC,  // H265
+	H264,
+	HEVC,  // H265
 
 	// TODO: Add audio codecs
 	WAV,
diff --git a/python/ftl/ftlstream.py b/python/ftl/ftlstream.py
index 6031e757d..169781202 100644
--- a/python/ftl/ftlstream.py
+++ b/python/ftl/ftlstream.py
@@ -12,8 +12,6 @@ from . misc import is_iframe
 from . import ftltypes as ftl
 from . import libde265
 
-_calib_fmt = "@ddddIIdddd"
-
 try:
     import cv2 as cv
     
@@ -44,10 +42,10 @@ except ImportError:
         return rgb.round().astype(np.uint8)
 
 class FTLStreamWriter:
-    def __init__(self, file):
+    def __init__(self, file, version=2):
         self._file = open(file, "wb")
         self._file.write(bytes(ord(c) for c in "FTLF")) # magic
-        self._file.write(bytes([2]))                    # version
+        self._file.write(bytes([version]))              # version
         self._file.write(bytes([0]*64))                 # reserved
 
         self._packer = msgpack.Packer(strict_types=False, use_bin_type=True)
@@ -134,7 +132,8 @@ class FTLStreamWriter:
         raise NotImplementedError("todo")
 
     def add_calibration(self, timestamp, source, data):
-        struct.pack(_calib_fmt, *data)
+        # todo: Use msgpack format instead (ftlf v3+)
+        struct.pack("@ddddIIdddd", *data)
         raise NotImplementedError("todo")
 
 class FTLStreamReader:
@@ -180,8 +179,17 @@ class FTLStreamReader:
     
     def _update_calib(self, sp, p):
         ''' Update calibration. '''
-        calibration = struct.unpack(_calib_fmt, p.data[:(4*8+2*4+4*8)])
-        self._calibration[sp.streamID] = ftl.Camera._make(calibration)
+        
+        if p.codec == ftl.codec_t.MSGPACK:
+            # TODO: What is in (unpacked) p.data[1:]? Contents discarded at the moment
+            self._calibration[sp.streamID] = ftl.Camera._make(msgpack.unpackb(p.data)[0])
+            
+        elif p.codec == ftl.codec_t.CALIBRATION:
+            calibration = struct.unpack("@ddddIIdddd", p.data[:(4*8+2*4+4*8)])
+            self._calibration[sp.streamID] = ftl.Camera._make(calibration)
+            
+        else:
+            raise Exception("Unknown codec %i for calibration" % p.codec)
 
     def _update_pose(self, sp, p):
         ''' Update pose '''
@@ -257,37 +265,33 @@ class FTLStreamReader:
         todo: make decoding optional
         '''
         self._frame = None
-
+        
         try:
             self._sp, self._p = self._read_next()
             self._packets_read += 1
         
         except msgpack.OutOfData:
             return False
-
+        
         if self._p.block_total != 1 or self._p.block_number != 0:
             raise Exception("Unsupported block format (todo)")
 
-        if self._p.codec == ftl.codec_t.JSON:
-            self._process_json(self._sp, self._p)
-
-        elif self._p.codec == ftl.codec_t.CALIBRATION:
+        if self._sp.channel == ftl.Channel.Calibration:
             self._update_calib(self._sp, self._p)
 
-        elif self._p.codec == ftl.codec_t.POSE:
+        elif self._sp.channel == ftl.Channel.Pose:
             self._update_pose(self._sp, self._p)
 
-        elif self._p.codec == ftl.codec_t.HEVC:
-            self._decode_hevc(self._sp, self._p)
-
-        elif self._p.codec == ftl.codec_t.PNG:
-            self._decode_opencv(self._sp, self._p)
+        elif self._sp.channel in (ftl.Channel.Left,ftl.Channel.Left):
+            # Decode Left/Right
+            if self._p.codec == ftl.codec_t.HEVC:
+                self._decode_hevc(self._sp, self._p)
 
-        elif self._p.codec == ftl.codec_t.JPG:
-            self._decode_opencv(self._sp, self._p)
+            elif self._p.codec == ftl.codec_t.PNG:
+                self._decode_opencv(self._sp, self._p)
 
-        else:
-            raise Exception("unkowno codec %i" % self._p.codec)
+            elif self._p.codec == ftl.codec_t.JPG:
+                self._decode_opencv(self._sp, self._p)
 
         return True
 
diff --git a/python/ftl/ftltypes.py b/python/ftl/ftltypes.py
index 17980b808..69eb87248 100644
--- a/python/ftl/ftltypes.py
+++ b/python/ftl/ftltypes.py
@@ -65,7 +65,9 @@ class codec_t(IntEnum):
     JSON = 100
     CALIBRATION = 101
     POSE = 102
-    RAW = 103
+    MSGPACK = 103,
+    STRING = 104,
+    RAW = 105
 
 definition_t = {
     0 : (7680, 4320),
@@ -85,4 +87,3 @@ def get_definition(shape):
 			return k
 	
 	return 7 # (None)
-
-- 
GitLab