[Filter/Custom] Add testcase. Fix bugs found by the testcase.
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Mon, 11 Jun 2018 09:33:37 +0000 (18:33 +0900)
committer함명주/동작제어Lab(SR)/Principal Engineer/삼성전자 <myungjoo.ham@samsung.com>
Thu, 14 Jun 2018 04:25:37 +0000 (13:25 +0900)
1. Added "passthrough with 3x280x4 tensors" Custom Filter Example
2. Added test case with the example.
3. Fixed filter/custom bugs with the test case
4. Relocated headers and their install paths

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
CMakeLists.txt
include/tensor_filter_custom.h [moved from tensor_filter/tensor_filter_custom.h with 99% similarity]
nnstreamer.pc.in
nnstreamer_example/CMakeLists.txt [new file with mode: 0644]
nnstreamer_example/custom_example_passthrough/CMakeLists.txt [new file with mode: 0644]
nnstreamer_example/custom_example_passthrough/nnstreamer_customfilter_example_passthrough.c [new file with mode: 0644]
tensor_filter/CMakeLists.txt
tensor_filter/tensor_filter_custom.c
tests/nnstreamer_filter_custom/runTest.sh [new file with mode: 0755]
tests/nnstreamer_filter_custom/testcase01.sh [new file with mode: 0755]

index 5e17bfc..6ef37aa 100644 (file)
@@ -59,8 +59,8 @@ LINK_DIRECTORIES(${pkgs_LIBRARY_DIRS})
 FOREACH(flag ${pkgs_CFALGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror -fPIC")
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wall -Werror -fPIC")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror -fPIC -g")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wall -Werror -fPIC -g")
 
 # Provide common data
 ADD_LIBRARY(common STATIC common/tensor_common.c)
@@ -76,12 +76,20 @@ TARGET_LINK_LIBRARIES(unittest_common ${pkgs_LIBRARIES} ${gtestLink})
 ADD_SUBDIRECTORY(tensor_converter)
 ADD_SUBDIRECTORY(tensor_filter)
 ADD_SUBDIRECTORY(tensor_decoder)
+ADD_SUBDIRECTORY(nnstreamer_example)
 
 CONFIGURE_FILE(nnstreamer.pc.in nnstreamer.pc @ONLY)
 
+# For nnstreamer users (gst app developers using via gstreamer API)
 INSTALL(FILES include/tensor_typedef.h
        DESTINATION ${INCLUDE_INSTALL_DIR}/nnstreamer
        )
+
+# For nnstreamer custom filter developers
+INSTALL(FILES include/tensor_common.h include/tensor_filter_custom.h
+       DESTINATION ${INCLUDE_INSTALL_DIR}/nnstreamer
+       )
+
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/nnstreamer.pc
        DESTINATION ${LIB_INSTALL_DIR}/pkgconfig
        )
similarity index 99%
rename from tensor_filter/tensor_filter_custom.h
rename to include/tensor_filter_custom.h
index 791416e..c182f3b 100644 (file)
@@ -61,6 +61,7 @@
 #define __NNS_TENSOR_FILTER_CUSTOM_H__
 
 #include <stdint.h>
+#include <tensor_common.h>
 
 /**
  * @brief A function that is called before calling other functions.
index 75a2f16..efb4b91 100644 (file)
@@ -10,4 +10,4 @@ Description: Neural Network Suite for GStreamer
 Version: @VERSION@
 Requires:
 Libs:
-Cflags: -I${includedir}
+Cflags: -I${includedir}/nnstreamer
diff --git a/nnstreamer_example/CMakeLists.txt b/nnstreamer_example/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f14578b
--- /dev/null
@@ -0,0 +1,3 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+ADD_SUBDIRECTORY(custom_example_passthrough)
diff --git a/nnstreamer_example/custom_example_passthrough/CMakeLists.txt b/nnstreamer_example/custom_example_passthrough/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0f3c917
--- /dev/null
@@ -0,0 +1,13 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+ADD_LIBRARY(nnstreamer_customfilter_passthrough SHARED nnstreamer_customfilter_example_passthrough.c)
+
+TARGET_LINK_LIBRARIES(nnstreamer_customfilter_passthrough ${pkgs_LIBRARIES})
+TARGET_INCLUDE_DIRECTORIES(nnstreamer_customfilter_passthrough PUBLIC ${pkgs_INCLUDE_DIRS})
+TARGET_COMPILE_OPTIONS(nnstreamer_customfilter_passthrough PUBLIC ${pkgs_CFLAGS_OTHER})
+
+INSTALL(TARGETS nnstreamer_customfilter_passthrough
+       RUNTIME DESTINATION ${EXEC_PREFIX}
+       LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+       ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+       )
diff --git a/nnstreamer_example/custom_example_passthrough/nnstreamer_customfilter_example_passthrough.c b/nnstreamer_example/custom_example_passthrough/nnstreamer_customfilter_example_passthrough.c
new file mode 100644 (file)
index 0000000..e8d00ac
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * NNStreamer Custom Filter Example 1. Pass-Through
+ * Copyright (C) 2018 MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * LICENSE: Apache-2.0
+ *
+ * @file       nnstreamer_customfilter_example_passthrough.c
+ * @date       11 Jun 2018
+ * @brief      Custom NNStreamer Filter Example 1. "Pass-Through"
+ * @author     MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * As a test, before #71 is resolved, this will support "3x280x40" uint8 tensors.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <tensor_filter_custom.h>
+
+#define D1     (3)
+#define D2     (280)
+#define D3     (40)
+
+typedef struct _pt_data {
+  uint32_t id; /***< Just for testing */
+  uint32_t dim[NNS_TENSOR_RANK_LIMIT];
+  tensor_type type;
+} pt_data;
+
+static void *pt_init() {
+  pt_data *data = (pt_data *)malloc(sizeof (pt_data));
+  int i;
+
+  data->id = 0;
+  data->dim[0] = D1;
+  data->dim[1] = D2;
+  data->dim[2] = D3;
+  for (i = 3; i < NNS_TENSOR_RANK_LIMIT; i++)
+    data->dim[i] = 1;
+  data->type = _NNS_UINT8;
+
+  return data;
+}
+
+static void pt_exit(void *private_data) {
+  pt_data *data = private_data;
+  g_assert(data);
+  free(data);
+}
+
+static int get_inputDim(void *private_data, uint32_t inputDimension[NNS_TENSOR_RANK_LIMIT], tensor_type *type) {
+  pt_data *data = private_data;
+  int i;
+
+  g_assert(data);
+  g_assert(NNS_TENSOR_RANK_LIMIT >= 3);
+  inputDimension[0] = D1;
+  inputDimension[1] = D2;
+  inputDimension[2] = D3;
+  for (i = 3; i < NNS_TENSOR_RANK_LIMIT; i++)
+    inputDimension[i] = 1;
+  *type = _NNS_UINT8;
+  return 0;
+  return 0;
+}
+
+static int get_outputDim(void *private_data, uint32_t outputDimension[NNS_TENSOR_RANK_LIMIT], tensor_type *type) {
+  pt_data *data = private_data;
+  int i;
+
+  g_assert(data);
+  g_assert(NNS_TENSOR_RANK_LIMIT >= 3);
+  outputDimension[0] = D1;
+  outputDimension[1] = D2;
+  outputDimension[2] = D3;
+  for (i = 3; i < NNS_TENSOR_RANK_LIMIT; i++)
+    outputDimension[i] = 1;
+  *type = _NNS_UINT8;
+  return 0;
+}
+
+static int pt_invoke(void *private_data, uint8_t *inptr, uint8_t *outptr) {
+  pt_data *data = private_data;
+  size_t size;
+
+  g_assert(data);
+  g_assert(inptr);
+  g_assert(outptr);
+
+  size = get_tensor_element_count(data->dim) * tensor_element_size[data->type];
+
+  g_assert(inptr != outptr);
+  memcpy(outptr, inptr, size);
+
+  return 0;
+}
+
+static NNStreamer_custom_class NNStreamer_custom_body = {
+  .initfunc = pt_init,
+  .exitfunc = pt_exit,
+  .getInputDim = get_inputDim,
+  .getOutputDim = get_outputDim,
+  .invoke = pt_invoke,
+};
+
+/* The dyn-loaded object */
+NNStreamer_custom_class *NNStreamer_custom = &NNStreamer_custom_body;
+
index 1db2d76..c0e9fc2 100644 (file)
@@ -15,6 +15,3 @@ INSTALL(TARGETS tensor_filter
        LIBRARY DESTINATION ${LIB_INSTALL_DIR}
        ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
        )
-INSTALL(FILES tensor_filter_custom.h
-       DESTINATION ${INCLUDE_INSTALL_DIR}/nnstreamer
-       )
index 1a950a7..491de97 100644 (file)
@@ -80,7 +80,7 @@ static int custom_loadlib(GstTensor_Filter *filter) {
     return 1;
   }
 
-  ptr = g_new0(internal_data, 0); /* Fill Zero! */
+  ptr = g_new0(internal_data, 1); /* Fill Zero! */
   filter->privateData = ptr;
   ptr->parent = filter;
 
@@ -93,7 +93,7 @@ static int custom_loadlib(GstTensor_Filter *filter) {
   }
 
   dlerror();
-  ptr->methods = (NNStreamer_custom_class *) dlsym(ptr->handle, "NNStreamer_custom");
+  ptr->methods = *((NNStreamer_custom_class **) dlsym(ptr->handle, "NNStreamer_custom"));
   dlsym_error = dlerror();
   if (dlsym_error) {
     g_printerr("tensor_filter_custom:loadlib error: %s\n", dlsym_error);
@@ -103,6 +103,7 @@ static int custom_loadlib(GstTensor_Filter *filter) {
     return -1;
   }
 
+  g_assert(ptr->methods->initfunc);
   ptr->customFW_private_data = ptr->methods->initfunc();
   return 0;
 }
diff --git a/tests/nnstreamer_filter_custom/runTest.sh b/tests/nnstreamer_filter_custom/runTest.sh
new file mode 100755 (executable)
index 0000000..a529ff3
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+failed=0
+sopath=""
+
+./testcase01.sh $sopath || failed=1
+
+echo ""
+echo ""
+echo "=================================================="
+echo "            Test for tensor_filter_custom"
+echo "=================================================="
+if [ "$failed" -eq "0" ]
+then
+  echo SUCCESS
+  echo ""
+  exit 0
+else
+  echo FAILED
+  echo ""
+  exit -1
+fi
diff --git a/tests/nnstreamer_filter_custom/testcase01.sh b/tests/nnstreamer_filter_custom/testcase01.sh
new file mode 100755 (executable)
index 0000000..42e2f9f
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+##
+# Copyright (C) 2018 Samsung Electronics
+# License: Apache-2.0
+#
+# @file testcase01.sh
+# @brief Test tensor_converter for testcase 01
+# @author MyungJoo Ham <myungjoo.ham@samsung.com>
+# @dependency cmp
+
+if [ $# -eq 0 ]
+then
+  PATH_TO_PLUGIN="$PWD/../../build/tensor_converter:$PWD/../../build/tensor_filter"
+else
+  PATH_TO_PLUGIN="$1"
+fi
+
+PATH_TO_MODEL="../../build/nnstreamer_example/custom_example_passthrough/libnnstreamer_customfilter_passthrough.so"
+
+failed=0
+
+# Generate one frame only (num-buffers=1)
+
+gst-launch-1.0 -v --gst-debug=GST_CAPS:4 --gst-plugin-path=${PATH_TO_PLUGIN} videotestsrc num-buffers=1 ! video/x-raw,format=RGB,width=280,height=40,framerate=0/1 ! videoconvert ! video/x-raw, format=RGB ! tensor_converter silent=FALSE ! tee name=t ! queue ! tensor_filter debug=TRUE framework='custom' model="${PATH_TO_MODEL}" input='3:280:40' inputtype='uint8' output='3:280:40' outputtype='uint8' ! filesink location="testcase01.passthrough.log" sync=true t. ! queue ! filesink location="testcase01.direct.log" sync=true || failed=1
+
+# Check the results (test.rgb.log, test.bgrx.log)
+cmp testcase01.passthrough.log testcase01.direct.log || failed=1
+
+if [ "$failed" -eq "0" ]
+then
+  echo Testcase 01: SUCCESS
+  exit 0
+else
+  echo Testcase 01: FAILED
+  exit -1
+fi