[Single Binary] Merge converter and aggregator into a single plugin binary
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Thu, 11 Oct 2018 08:38:15 +0000 (17:38 +0900)
committerMyungJoo Ham <myungjoo.ham@gmail.com>
Fri, 12 Oct 2018 12:49:57 +0000 (21:49 +0900)
This is a pilot program for #628

We are going to merge all nnstreamer plugins into one single plugin binary.

Use -DSINGLE_BINARY to generate a single plugin binary with all plugin elements.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
CMakeLists.txt
gst/nnstreamer/nnstreamer.c [new file with mode: 0644]
gst/tensor_aggregator/CMakeLists.txt
gst/tensor_aggregator/tensor_aggregator.c
gst/tensor_converter/CMakeLists.txt
gst/tensor_converter/tensor_converter.c
gst/tensor_filter/CMakeLists.txt
include/tensor_common.h
packaging/nnstreamer.spec
tests/testAPI.sh

index 2895be3..e557f44 100644 (file)
@@ -6,6 +6,10 @@ OPTION(TIZEN "Enable Tizen build mode" OFF)
 OPTION(DISABLE_TENSORFLOW_LITE "Disable tensorflow-lite support" OFF)
 OPTION(DISABLE_TENSORFLOW "Disable tensorflow support" OFF)
 OPTION(INSTALL_EXAMPLE_APP "Install example applications" OFF)
+OPTION(SINGLE_BINARY "Generate a single binary for all nnstreamer elements" OFF)
+IF(SINGLE_BINARY)
+       ADD_DEFINITIONS(-DSINGLE_BINARY)
+ENDIF(SINGLE_BINARY)
 
 ADD_DEFINITIONS(-DVERSION="0.0.1")
 
@@ -94,8 +98,12 @@ ADD_EXECUTABLE(unittest_sink tests/nnstreamer_sink/unittest_sink.cpp ${gtestSrc}
 TARGET_INCLUDE_DIRECTORIES(unittest_sink PUBLIC ${pkgs_INCLUDE_DIRS} ${gtestInc})
 TARGET_LINK_LIBRARIES(unittest_sink ${pkgs_LIBRARIES} ${gtestLink})
 
-ADD_SUBDIRECTORY(gst/tensor_aggregator)
-ADD_SUBDIRECTORY(gst/tensor_converter)
+# Supported projects for the single binary
+SET(PROJECTS
+       tensor_converter
+       tensor_aggregator
+)
+
 ADD_SUBDIRECTORY(gst/tensor_filter)
 ADD_SUBDIRECTORY(gst/tensor_decoder)
 ADD_SUBDIRECTORY(gst/tensor_sink)
@@ -110,6 +118,48 @@ ADD_SUBDIRECTORY(tests/nnstreamer_tensors/tensors_test)
 enable_testing()
 ADD_SUBDIRECTORY(tests)
 
+SET(OBJECTS)
+FOREACH(PRJ IN LISTS PROJECTS)
+       ADD_SUBDIRECTORY(gst/${PRJ})
+       LIST(APPEND OBJECTS $<TARGET_OBJECTS:${PRJ}OBJ>)
+ENDFOREACH(PRJ)
+
+
+IF (SINGLE_BINARY)
+       ADD_LIBRARY(nnstreamerStatic STATIC gst/nnstreamer/nnstreamer.c ${OBJECTS})
+       TARGET_INCLUDE_DIRECTORIES(nnstreamerStatic PUBLIC ${pkgs_INCLUDE_DIRS})
+       TARGET_COMPILE_OPTIONS(nnstreamerStatic PUBLIC ${pkgs_CFLAGS_OTHER})
+       TARGET_LINK_LIBRARIES(nnstreamerStatic ${pkgs_LIBRARIES})
+       ADD_LIBRARY(nnstreamer SHARED gst/nnstreamer/nnstreamer.c ${OBJECTS})
+       TARGET_INCLUDE_DIRECTORIES(nnstreamer PUBLIC ${pkgs_INCLUDE_DIRS})
+       TARGET_COMPILE_OPTIONS(nnstreamer PUBLIC ${pkgs_CFLAGS_OTHER})
+       TARGET_LINK_LIBRARIES(nnstreamer ${pkgs_LIBRARIES})
+
+       INSTALL(TARGETS nnstreamerStatic nnstreamer
+               RUNTIME DESTINATION ${EXEC_PREFIX}
+               LIBRARY DESTINATION ${GST_INSTALL_DIR}
+               ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+       )
+ELSE (SINGLE_BINARY)
+       FOREACH(PRJ IN LISTS PROJECTS)
+               ADD_LIBRARY(${PRJ}Static STATIC $<TARGET_OBJECTS:${PRJ}OBJ>)
+               TARGET_INCLUDE_DIRECTORIES(${PRJ}Static PUBLIC ${pkgs_INCLUDE_DIRS})
+               TARGET_COMPILE_OPTIONS(${PRJ}Static PUBLIC ${pkgs_CFLAGS_OTHER})
+               TARGET_LINK_LIBRARIES(${PRJ}Static ${pkgs_LIBRARIES})
+               ADD_LIBRARY(${PRJ} SHARED $<TARGET_OBJECTS:${PRJ}OBJ>)
+               TARGET_INCLUDE_DIRECTORIES(${PRJ} PUBLIC ${pkgs_INCLUDE_DIRS})
+               TARGET_COMPILE_OPTIONS(${PRJ} PUBLIC ${pkgs_CFLAGS_OTHER})
+               TARGET_LINK_LIBRARIES(${PRJ} ${pkgs_LIBRARIES})
+
+               INSTALL(TARGETS ${PRJ}Static ${PRJ}
+                       RUNTIME DESTINATION ${EXEC_PREFIX}
+                       LIBRARY DESTINATION ${GST_INSTALL_DIR}
+                       ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+               )
+       ENDFOREACH(PRJ)
+ENDIF (SINGLE_BINARY)
+
+
 CONFIGURE_FILE(nnstreamer.pc.in nnstreamer.pc @ONLY)
 
 # For nnstreamer users (gst app developers using via gstreamer API)
diff --git a/gst/nnstreamer/nnstreamer.c b/gst/nnstreamer/nnstreamer.c
new file mode 100644 (file)
index 0000000..7a6eb94
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * nnstreamer registerer
+ * Copyright (C) 2018 MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ */
+
+/**
+ * @file       nnstreamer.c
+ * @date       11 Oct 2018
+ * @brief      Registers all nnstreamer plugins for gstreamer so that we can have a single big binary
+ * @see                https://github.com/nnsuite/nnstreamer
+ * @author     MyungJoo Ham <myungjoo.ham@samsung.com>
+ * @bug                No known bugs except for NYI items
+ */
+
+#include <gst/gst.h>
+#include <gst/gstplugin.h>
+
+#define NNSTREAMER_PLUGIN(name) \
+  extern gboolean G_PASTE(nnstreamer_export_, name) (GstPlugin *plugin)
+
+NNSTREAMER_PLUGIN (tensor_converter);
+NNSTREAMER_PLUGIN (tensor_aggregator);
+
+#define NNSTREAMER_INIT(name, plugin) \
+  do { \
+    if (!G_PASTE(nnstreamer_export_, name)(plugin)) \
+      return FALSE; \
+  } while (0);
+
+/**
+ * @brief Function to initialize all nnstreamer elements
+ */
+static gboolean
+gst_nnstreamer_init (GstPlugin * plugin)
+{
+  NNSTREAMER_INIT (tensor_converter, plugin);
+  NNSTREAMER_INIT (tensor_aggregator, plugin);
+
+  return TRUE;
+}
+
+#ifndef SINGLE_BINARY
+#error SINGLE_BINARY must be defined
+#endif
+
+#ifndef PACKAGE
+#define PACKAGE "nnstreamer"
+#endif
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    nnstreamer,
+    "nnstreamer plugin library",
+    gst_nnstreamer_init, VERSION, "LGPL", "nnstreamer",
+    "https://github.com/nnsuite/nnstreamer");
index b64a8df..14269b5 100644 (file)
@@ -1,15 +1 @@
-ADD_LIBRARY(tensor_aggregator SHARED tensor_aggregator.c)
-ADD_LIBRARY(tensor_aggregatorStatic STATIC tensor_aggregator.c)
-
-TARGET_LINK_LIBRARIES(tensor_aggregator ${pkgs_LIBRARIES})
-TARGET_INCLUDE_DIRECTORIES(tensor_aggregator PUBLIC ${pkgs_INCLUDE_DIRS})
-TARGET_COMPILE_OPTIONS(tensor_aggregator PUBLIC ${pkgs_CFLAGS_OTHER})
-TARGET_LINK_LIBRARIES(tensor_aggregatorStatic ${pkgs_LIBRARIES})
-TARGET_INCLUDE_DIRECTORIES(tensor_aggregatorStatic PUBLIC ${pkgs_INCLUDE_DIRS})
-TARGET_COMPILE_OPTIONS(tensor_aggregatorStatic PUBLIC ${pkgs_CFLAGS_OTHER})
-
-INSTALL(TARGETS tensor_aggregator tensor_aggregatorStatic
-       RUNTIME DESTINATION ${EXEC_PREFIX}
-       LIBRARY DESTINATION ${GST_INSTALL_DIR}
-       ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
-       )
+ADD_LIBRARY(tensor_aggregatorOBJ OBJECT tensor_aggregator.c)
index 96b19c5..d9ddd7a 100644 (file)
@@ -1013,8 +1013,7 @@ gst_tensor_aggregator_parse_caps (GstTensorAggregator * self,
  *
  * See GstPluginInitFunc() for more details.
  */
-static gboolean
-gst_tensor_aggregator_plugin_init (GstPlugin * plugin)
+NNSTREAMER_PLUGIN_INIT (tensor_aggregator)
 {
   GST_DEBUG_CATEGORY_INIT (gst_tensor_aggregator_debug, "tensor_aggregator",
       0, "tensor_aggregator element");
@@ -1035,6 +1034,7 @@ gst_tensor_aggregator_plugin_init (GstPlugin * plugin)
 #define PACKAGE "tensor_aggregator"
 #endif
 
+#ifndef SINGLE_BINARY
 /**
  * @brief Macro to define the entry point of the plugin.
  */
@@ -1044,3 +1044,4 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
     "GStreamer plugin to aggregate tensor stream",
     gst_tensor_aggregator_plugin_init, VERSION, "LGPL", "GStreamer",
     "http://gstreamer.net/");
+#endif
index d50bbc6..e0b4eb2 100644 (file)
@@ -1,15 +1 @@
-ADD_LIBRARY(tensor_converter SHARED tensor_converter.c)
-ADD_LIBRARY(tensor_converterStatic STATIC tensor_converter.c)
-
-TARGET_LINK_LIBRARIES(tensor_converter ${pkgs_LIBRARIES})
-TARGET_INCLUDE_DIRECTORIES(tensor_converter PUBLIC ${pkgs_INCLUDE_DIRS})
-TARGET_COMPILE_OPTIONS(tensor_converter PUBLIC ${pkgs_CFLAGS_OTHER})
-TARGET_LINK_LIBRARIES(tensor_converterStatic ${pkgs_LIBRARIES})
-TARGET_INCLUDE_DIRECTORIES(tensor_converterStatic PUBLIC ${pkgs_INCLUDE_DIRS})
-TARGET_COMPILE_OPTIONS(tensor_converterStatic PUBLIC ${pkgs_CFLAGS_OTHER})
-
-INSTALL(TARGETS tensor_converter tensor_converterStatic
-       RUNTIME DESTINATION ${EXEC_PREFIX}
-       LIBRARY DESTINATION ${GST_INSTALL_DIR}
-       ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
-       )
+ADD_LIBRARY(tensor_converterOBJ OBJECT tensor_converter.c)
index 316d2ff..e9da659 100644 (file)
@@ -876,8 +876,7 @@ gst_tensor_converter_parse_caps (GstTensorConverter * self,
  *
  * See GstPluginInitFunc() for more details.
  */
-static gboolean
-gst_tensor_converter_plugin_init (GstPlugin * plugin)
+NNSTREAMER_PLUGIN_INIT (tensor_converter)
 {
   GST_DEBUG_CATEGORY_INIT (gst_tensor_converter_debug, "tensor_converter",
       0, "tensor_converter element");
@@ -898,6 +897,7 @@ gst_tensor_converter_plugin_init (GstPlugin * plugin)
 #define PACKAGE "tensor_converter"
 #endif
 
+#ifndef SINGLE_BINARY
 /**
  * @brief Macro to define the entry point of the plugin.
  */
@@ -906,4 +906,5 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
     tensor_converter,
     "GStreamer plugin to convert media types to tensors",
     gst_tensor_converter_plugin_init, VERSION, "LGPL", "GStreamer",
-    "http://gstreamer.net/");
+    "http://github.com/nnsuite/nnstreamer/");
+#endif
index 7a7d5c6..0f66fb2 100644 (file)
@@ -2,13 +2,14 @@
 # DISABLE_TENSORFLOW_LITE is defined at /debian/rules according to the build environment
 
 set(FILTER_SOURCE tensor_filter.c tensor_filter_custom.c)
-set(FILTER_LIB tensor_filter)
-set(FILTER_TARGET tensor_filter)
+set(FILTER_LIB )
+set(FILTER_TARGET tensor_filter tensor_filterStatic)
 
 IF(NOT DISABLE_TENSORFLOW_LITE)
   list(APPEND FILTER_SOURCE tensor_filter_tensorflow_lite.c)
   list(APPEND FILTER_LIB tensor_filter_tflitecore)
   list(APPEND FILTER_TARGET tensor_filter_tflitecore)
+  list(APPEND FILTER_TARGET tensor_filter_tflitecoreStatic)
   PKG_CHECK_MODULES(TENSORFLOW_LITE REQUIRED tensorflow-lite)
   LINK_DIRECTORIES(${TENSORFLOW_LITE_LIBRARY_DIRS})
 ENDIF(NOT DISABLE_TENSORFLOW_LITE)
@@ -17,6 +18,7 @@ IF(NOT DISABLE_TENSORFLOW)
   list(APPEND FILTER_SOURCE tensor_filter_tensorflow.c)
   list(APPEND FILTER_LIB tensor_filter_tfcore)
   list(APPEND FILTER_TARGET tensor_filter_tfcore)
+  list(APPEND FILTER_TARGET tensor_filter_tfcoreStatic)
   PKG_CHECK_MODULES(TENSORFLOW REQUIRED tensorflow)
   LINK_DIRECTORIES(${TENSORFLOW_LIBRARY_DIRS})
 ENDIF(NOT DISABLE_TENSORFLOW)
@@ -24,9 +26,15 @@ ENDIF(NOT DISABLE_TENSORFLOW)
 ADD_LIBRARY(tensor_filter SHARED
   ${FILTER_SOURCE}
   )
-TARGET_LINK_LIBRARIES(${FILTER_LIB} dl ${pkgs_LIBRARIES})
+ADD_LIBRARY(tensor_filterStatic STATIC
+  ${FILTER_SOURCE}
+  )
+TARGET_LINK_LIBRARIES(tensor_filter ${FILTER_LIB} dl ${pkgs_LIBRARIES})
 TARGET_INCLUDE_DIRECTORIES(tensor_filter PUBLIC ${pkgs_INCLUDE_DIRS})
 TARGET_COMPILE_OPTIONS(tensor_filter PUBLIC ${pkgs_CFLAGS_OTHER})
+TARGET_LINK_LIBRARIES(tensor_filterStatic ${FILTER_LIB} dl ${pkgs_LIBRARIES})
+TARGET_INCLUDE_DIRECTORIES(tensor_filterStatic PUBLIC ${pkgs_INCLUDE_DIRS})
+TARGET_COMPILE_OPTIONS(tensor_filterStatic PUBLIC ${pkgs_CFLAGS_OTHER})
 
 IF(DISABLE_TENSORFLOW_LITE) # NOT AVAILABLE
   ADD_DEFINITIONS(-DDISABLE_TENSORFLOW_LITE)
@@ -45,6 +53,15 @@ IF(NOT DISABLE_TENSORFLOW_LITE) # AVAILABLE
   TARGET_LINK_LIBRARIES(tensor_filter_tflitecore ${pkgs_LIBRARIES} tensorflow-lite)
   TARGET_INCLUDE_DIRECTORIES(tensor_filter_tflitecore PUBLIC ${pkgs_INCLUDE_DIRS} ${TENSORFLOW_LITE_INCLUDE_DIRS})
   TARGET_COMPILE_OPTIONS(tensor_filter_tflitecore PUBLIC ${pkgs_CFLAGS_OTHER})
+
+  ADD_LIBRARY(tensor_filter_tflitecoreStatic STATIC
+    tensor_filter_tensorflow_lite_core.cc
+    )
+
+  TARGET_LINK_LIBRARIES(tensor_filter_tflitecoreStatic ${pkgs_LIBRARIES} tensorflow-lite)
+  TARGET_INCLUDE_DIRECTORIES(tensor_filter_tflitecoreStatic PUBLIC ${pkgs_INCLUDE_DIRS} ${TENSORFLOW_LITE_INCLUDE_DIRS})
+  TARGET_COMPILE_OPTIONS(tensor_filter_tflitecoreStatic PUBLIC ${pkgs_CFLAGS_OTHER})
+
   SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wno-sign-compare")
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wno-sign-compare")
 ENDIF(NOT DISABLE_TENSORFLOW_LITE) # AVAILABLE
@@ -57,6 +74,15 @@ IF(NOT DISABLE_TENSORFLOW) # AVAILABLE
   TARGET_LINK_LIBRARIES(tensor_filter_tfcore ${pkgs_LIBRARIES} ${TENSORFLOW_LIBRARIES})
   TARGET_INCLUDE_DIRECTORIES(tensor_filter_tfcore PUBLIC ${pkgs_INCLUDE_DIRS} ${TENSORFLOW_INCLUDE_DIRS})
   TARGET_COMPILE_OPTIONS(tensor_filter_tfcore PUBLIC ${pkgs_CFLAGS_OTHER})
+
+  ADD_LIBRARY(tensor_filter_tfcoreStatic STATIC
+    tensor_filter_tensorflow_core.cc
+    )
+
+  TARGET_LINK_LIBRARIES(tensor_filter_tfcoreStatic ${pkgs_LIBRARIES} ${TENSORFLOW_LIBRARIES})
+  TARGET_INCLUDE_DIRECTORIES(tensor_filter_tfcoreStatic PUBLIC ${pkgs_INCLUDE_DIRS} ${TENSORFLOW_INCLUDE_DIRS})
+  TARGET_COMPILE_OPTIONS(tensor_filter_tfcoreStatic PUBLIC ${pkgs_CFLAGS_OTHER})
+
 ENDIF(NOT DISABLE_TENSORFLOW) # AVAILABLE
 
 INSTALL(TARGETS ${FILTER_TARGET}
index 7f8ebdf..d3396e0 100644 (file)
@@ -31,6 +31,7 @@
 #include <gst/gst.h>
 #include <gst/video/video-format.h>
 #include <gst/audio/audio-format.h>
+#include <gst/gstplugin.h>
 
 G_BEGIN_DECLS
 
@@ -415,6 +416,13 @@ extern void gst_tensors_typefind_function (GstTypeFind * tf, gpointer pdata);
         gst_caps_new_simple ("other/tensorsave", NULL, NULL), NULL, NULL)); \
     } while (0)
 
-G_END_DECLS
+#ifdef SINGLE_BINARY
+#define NNSTREAMER_PLUGIN_INIT(name)   \
+  gboolean G_PASTE(nnstreamer_export_, name) (GstPlugin * plugin)
+#else
+#define NNSTREAMER_PLUGIN_INIT(name)   \
+  static gboolean G_PASTE(G_PASTE(gst_, name), _plugin_init) (GstPlugin * plugin)
+#endif
 
+G_END_DECLS
 #endif /* __GST_TENSOR_COMMON_H__ */
index dcdee50..634c647 100644 (file)
@@ -91,7 +91,7 @@ export LD_LIBRARY_PATH=%{buildroot}%{gstlibdir}
 
 pushd build
 ./unittest_common
-./unittest_sink --gst-plugin-path=./gst
+./unittest_sink --gst-plugin-path=%{buildroot}%{_libdir}
 popd
 
 pushd tests
index 7dd9cb1..a82c34d 100644 (file)
@@ -15,7 +15,7 @@ if [[ $# -eq 0 ]]; then
                        fi
                fi
        fi
-       PATH_TO_PLUGIN="$dirpath/../build/gst"
+       PATH_TO_PLUGIN="$dirpath/../build/gst:$dirpath/../build"
 else
        PATH_TO_PLUGIN="$1"
 fi