[Tensorsave] Findtype file format definition.
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Mon, 23 Jul 2018 23:34:59 +0000 (08:34 +0900)
committer문지중/동작제어Lab(SR)/Principal Engineer/삼성전자 <jijoong.moon@samsung.com>
Wed, 25 Jul 2018 07:29:40 +0000 (16:29 +0900)
To allow save tensors as files with its medata in tact,
we define "other/tensorsave" type for gstreamer.

It can be used to share tensors with non-gstreamer programs,
or used to create testcases for nnstreamer plugins.

To be completed, we need to implement load and save plugins
in gst/tensor_saveload directory.

Fixes #29

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
common/tensor_common.c
gst/tensor_converter/README.md
gst/tensor_saveload/README.md [new file with mode: 0644]
include/tensor_common.h

index 7e9b7a2..23041ec 100644 (file)
@@ -245,3 +245,23 @@ get_tensor_from_padcap (const GstCaps * caps, tensor_dim dim,
   }
   return ret;
 }
+
+/**
+ * @brief A callback for typefind, trying to find whether a file is other/tensors or not.
+ * For the concrete definition of headers, please look at the wiki page of nnstreamer:
+ * https://github.com/nnsuite/nnstreamer/wiki/Design-External-Save-Format-for-other-tensor-and-other-tensors-Stream-for-TypeFind
+ */
+void
+gst_tensors_typefind_function (GstTypeFind * tf, gpointer pdata)
+{
+  const guint8 *data = gst_type_find_peek (tf, 0, 40);  /* The first 40 bytes are header-0 in v.1 protocol */
+  const char formatstr[] = "TENSORST";
+  const unsigned int *supported_version = (const unsigned int *) (&data[8]);
+  const unsigned int *num_tensors = (const unsigned int *) (&data[12]);
+  if (data &&
+      memcmp (data, formatstr, 8) == 0 &&
+      *supported_version == 1 && *num_tensors <= 16 && *num_tensors >= 1) {
+    gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM,
+        gst_caps_new_simple ("other/tensorsave", NULL, NULL));
+  }
+}
index cee5164..57a4c76 100644 (file)
@@ -25,3 +25,37 @@ From higher priority
   - framerate; fraction
 
   - data: (binary data, can be treated as an C array of [dim4][dim3][dim2][dim1])
+
+# other/tensors File Data Format, Version 1.0 Draft
+
+```
+Header-0: The first 20 bytes, global header
+=============================================================================================================
+|    8 bytes               |   4 bytes         |    4 bytes                  | 4 bytes                      |
+| The type header          | Protocol Version  | Number of tensors per frame | Frame size in bytes          |
+|           "TENSORST"     |    (uint32) 1     |  (uint32) 1~16 (N)          | (uint32) 1 ~ MAXUINT (S)     |
+|                          |                   | (v.1 supports up to 16)     | Counting data only (no meta) |
+=============================================================================================================
+|    20 bytes. RESERVED in v1.                                                                              |
+=============================================================================================================
+| Header-1: Following Header-1, Description of Tensor-1 of each frame (24 bytes)                   |
+| 4 bytes                           | 4 bytes              | 4 bytes | 4 bytes | 4 bytes | 4 bytes |
+| Element Type (enum)               | RANK (uint32)        | Dim-1   | Dime-2  | Dim-3   | Dim-4   |
+| "tensor_type" in tensor_typedef.h | v.1 supports 1 to 4. |         |         |         |         |
+====================================================================================================
+| ...                                                                                              |
+====================================================================================================
+| Header-N                                                                                         |
+====================================================================================================
+Data of frame-1, tensor-1 starts at the offset of (40 + 24 x N).
+Data of frame-1, tensor-i starts at the offset of (40 + 24 x N + Sum(x=1..i-1)(tensor_element_size[tensor-type of Tx] x dim1-of-Tx x dim2-of-Tx x dim3-of-Tx x dim4-of-Tx)).
+...
+Data of frame-F, tensor-1 starts at the offset of (40 + 24 x N + S x (F - 1))
+...
+Assert (S = Sum(x=1..N)(tensor_element_size[tensor-type of Tx] x dim1-of-Tx x dim2-of-Tx x dim3-of-Tx x dim4-of-Tx))
+
+Add a custom footer
+```
+
+Note that once the stream is loaded in GStreamer, tensor\_\* elements uses the data parts only without the headers.
+The header exists only when the tensor stream is stored as a file.
diff --git a/gst/tensor_saveload/README.md b/gst/tensor_saveload/README.md
new file mode 100644 (file)
index 0000000..705e9cc
--- /dev/null
@@ -0,0 +1,2 @@
+- tensor\_load: other/tensorsave to other/tensors or other/tensor
+- tensor\_save: other/tensors or other/tensor to other/tensorsave
index 95e43f3..df61133 100644 (file)
@@ -157,6 +157,19 @@ get_tensor_from_padcap(const GstCaps * caps, tensor_dim dim, tensor_type *type,
  */
 #define err_print(...) dlog_print(DLOG_ERROR, "nnstreamer", __VA_ARGS__)
 
+/**
+ * @brief A callback for typefind, trying to find whether a file is other/tensors or not.
+ * For the concrete definition of headers, please look at the wiki page of nnstreamer:
+ * https://github.com/nnsuite/nnstreamer/wiki/Design-External-Save-Format-for-other-tensor-and-other-tensors-Stream-for-TypeFind
+ */
+extern void gst_tensors_typefind_function (GstTypeFind *tf, gpointer pdata);
+
+#define GST_TENSOR_TYPEFIND_REGISTER(plugin)  do { \
+    gst_type_find_register (plugin, "other/tensorsave", \
+        GST_RANK_PRIMARY, gst_tensors_typefind_function, "tnsr", \
+        gst_caps_new_simple ("other/tensorsave", NULL, NULL), NULL, NULL)); \
+    } while (0)
+
 G_END_DECLS
 
 #endif /* __GST_TENSOR_COMMON_H__ */