[ANDROID] Built as Shared Library with tensorflow-lite
authorjijoong.moon <jijoong.moon@samsung.com>
Fri, 14 Jun 2019 04:23:35 +0000 (13:23 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Wed, 24 Jul 2019 05:29:27 +0000 (14:29 +0900)
In order to build nnstreamer shared libraries including
sub-plugins (decoder, filters), the android.mk file is
restructured. Becuse gstreamer building blocks list for nnstreamer might be
required for static build and android application build, it is moved
to nnstreamer.mk.

If you bulid libnnstreamer.so using this android.mk, gstreamer shared
libries should be prepared. Please refere "Build Gstreamer full source
based Android rootFS with Cerbero" in
https://github.com/nnsuite/nnstreamer-example/tree/master/android.

Once the build is finished successfully, you can find libnnstreamer.so
and gstreamer shared libraries in libs/$TARGET_ARCH/ which is listed
in nnstreamer.mk under the name of "NNSTREAMER_BUILDING_BLOCK_LIST".
you can use these to build your own android application.

New script for tensorflow-lite tensor filter library is added. If
there is not tflite source, "prepare_tflite.sh" will download and
prepare the external packages of tflite. Using these source code,
android.mk make tflite static library and use it to build
libnnstreamer_filter_tensorflow-lite.so (which includes static
tensorflowlite.a for android of course)

If you want to build android application statically, you could just use the
macro defined in nnstreamer.mk.

Build NNStreamer as Shared Library.
- Gstreamer Shared Libraries : Cerbero
  : Download and build by yourself
- Tensorflow-lite : If TENSORFLOW_LITE Macro is not defined,
  NNStreamer is going to download and configure
  --> static lib
- NNStreamer : libnnstreamer.so
- NNStreamer tflite : libnnstreamer_filter_tensorflow-lite.so
- NNStreamer decoder: libnnstreamer_decoder_direct_video.so
                      libnnstreamer_decoder_bounding_boxes.so
                      libnnstreamer_decoder_image_labeling.so

**Self evaluation:**
1. Build test:  [X]Passed [ ]Failed [ ]Skipped
2. Run test:  [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: jijoong.moon <jijoong.moon@samsung.com>
jni/Android.mk [new file with mode: 0644]
jni/nnstreamer.mk
jni/prepare_tflite.sh [new file with mode: 0755]

diff --git a/jni/Android.mk b/jni/Android.mk
new file mode 100644 (file)
index 0000000..b12a25e
--- /dev/null
@@ -0,0 +1,261 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+include $(LOCAL_PATH)/nnstreamer.mk
+
+ifndef NNSTREAMER_ROOT
+NNSTREAMER_ROOT := $(LOCAL_PATH)/..
+endif
+
+ifndef GSTREAMER_ROOT_ANDROID
+$(error GSTREAMER_ROOT_ANDROID is not defined!)
+endif
+
+ifeq ($(TARGET_ARCH_ABI),armeabi)
+GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/arm
+else ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/armv7
+else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
+GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/arm64
+else ifeq ($(TARGET_ARCH_ABI),x86)
+GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/x86
+else ifeq ($(TARGET_ARCH_ABI),x86_64)
+GSTREAMER_ROOT        := $(GSTREAMER_ROOT_ANDROID)/x86_64
+else
+$(error Target arch ABI not supported: $(TARGET_ARCH_ABI))
+endif
+
+# Define shared libraries that are required by a gstreamer plug-in.
+define shared_lib_common
+    include $(CLEAR_VARS)
+    LOCAL_MODULE := $(1)
+    LOCAL_SRC_FILES := $(GSTREAMER_ROOT)/lib/lib$(1).so
+    $(info $(GSTREAMER_ROOT)/lib/lib$(1).so)
+    include $(PREBUILT_SHARED_LIBRARY)
+endef
+
+# Define shared libraries that are used as a gstreamer plug-in.
+define shared_lib_gst
+    include $(CLEAR_VARS)
+    LOCAL_MODULE := $(1)
+    LOCAL_SRC_FILES := $(GSTREAMER_ROOT)/lib/gstreamer-1.0/lib$(1).so
+    $(info $(GSTREAMER_ROOT)/lib/gstreamer-1.0/lib$(1).so)
+    include $(PREBUILT_SHARED_LIBRARY)
+endef
+
+$(foreach item,$(GST_LIBS_COMMON),$(eval $(call shared_lib_common,$(item))))
+
+$(foreach item,$(GST_LIBS_GST),$(eval $(call shared_lib_gst,$(item))))
+
+ifeq ($(ENABLE_NNAPI), true)
+# Define shared libraries that are used as a gstreamer plug-in.
+define shared_lib_nnapi
+    include $(CLEAR_VARS)
+    LOCAL_MODULE := $(1)
+    LOCAL_SRC_FILES := $(NNSTREAMER_ROOT)/nnapi/lib$(1).so
+    include $(PREBUILT_SHARED_LIBRARY)
+endef
+
+$(foreach item,$(NNAPI_BUILDING_BLOCK),$(eval $(call shared_lib_nnapi,$(item))))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := backend_acl_common
+LOCAL_SRC_FILES := $(NNSTREAMER_ROOT)/nnapi/libbackend_acl_common.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+NNAPI_BUILDING_BLOCK_STATIC := backend_acl_common
+endif
+
+include $(CLEAR_VARS)
+
+# Please keep the pthread and openmp library for checking a compatibility
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -O0 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CXXFLAGS      += -std=c++11 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CFLAGS        += -pthread -fopenmp
+
+ifeq ($(NO_AUDIO), true)
+LOCAL_CFLAGS += -DNO_AUDIO
+LOCAL_CXXFLAGS += -DNO_AUDIO
+endif
+
+LOCAL_LDFLAGS       += -fuse-ld=bfd
+LOCAL_MODULE_TAGS   := optional
+
+LOCAL_MODULE        := nnstreamer
+LOCAL_SRC_FILES     := $(NNSTREAMER_COMMON_SRCS) $(NNSTREAMER_PLUGINS_SRCS)
+LOCAL_C_INCLUDES    := $(NNSTREAMER_INCLUDES)
+
+LOCAL_C_INCLUDES += $(GSTREAMER_ROOT)/include/gstreamer-1.0 \
+     $(GSTREAMER_ROOT)/include/glib-2.0 \
+     $(GSTREAMER_ROOT)/lib/glib-2.0/include \
+     $(GSTREAMER_ROOT)/include
+
+LOCAL_SHARED_LIBRARIES := $(GST_BUILDING_BLOCK_LIST)
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+ifndef TENSORFLOW_ROOT
+ifneq ($(MAKECMDGOALS),clean)
+$(warning TENSORFLOW_ROOT is not defined!)
+$(warning TENSORFLOW SRC is going to be downloaded!)
+
+# Currently we are using tensorflow 1.9.0
+$(info $(shell ($(LOCAL_PATH)/prepare_tflite.sh)))
+
+TENSORFLOW_ROOT := $(LOCAL_PATH)/tensorflow-1.9.0
+
+endif
+endif
+
+TF_LITE_DIR=$(TENSORFLOW_ROOT)/tensorflow/contrib/lite
+
+LOCAL_MODULE := tensorflow-lite
+TFLITE_SRCS := \
+    $(wildcard $(TF_LITE_DIR)/*.cc) \
+    $(wildcard $(TF_LITE_DIR)/kernels/*.cc) \
+    $(wildcard $(TF_LITE_DIR)/kernels/internal/*.cc) \
+    $(wildcard $(TF_LITE_DIR)/kernels/internal/optimized/*.cc) \
+    $(wildcard $(TF_LITE_DIR)/kernels/internal/reference/*.cc) \
+    $(wildcard $(TF_LITE_DIR)/*.c) \
+    $(wildcard $(TF_LITE_DIR)/kernels/*.c) \
+    $(wildcard $(TF_LITE_DIR)/kernels/internal/*.c) \
+    $(wildcard $(TF_LITE_DIR)/kernels/internal/optimized/*.c) \
+    $(wildcard $(TF_LITE_DIR)/kernels/internal/reference/*.c) \
+    $(wildcard $(TF_LITE_DIR)/downloads/farmhash/src/farmhash.cc) \
+    $(wildcard $(TF_LITE_DIR)/downloads/fft2d/fftsg.c)
+
+TFLITE_SRCS := $(sort $(TFLITE_SRCS))
+
+TFLITE_EXCLUDE_SRCS := \
+    $(wildcard $(TF_LITE_DIR)/*test.cc) \
+    $(wildcard $(TF_LITE_DIR)/*/*test.cc) \
+    $(wildcard $(TF_LITE_DIR)/*/*/*test.cc) \
+    $(wildcard $(TF_LITE_DIR)/*/*/*/*test.cc) \
+    $(wildcard $(TF_LITE_DIR)/kernels/test_util.cc) \
+    $(wildcard $(TF_LITE_DIR)/examples/minimal/minimal.cc)
+
+TFLITE_SRCS := $(filter-out $(TFLITE_EXCLUDE_SRCS), $(TFLITE_SRCS))
+# ANDROID_NDK env should be set before build
+TFLITE_INCLUDES := \
+    $(ANDROID_NDK)/../ \
+    $(TENSORFLOW_ROOT) \
+    $(TF_LITE_DIR)/downloads \
+    $(TF_LITE_DIR)/downloads/eigen \
+    $(TF_LITE_DIR)/downloads/gemmlowp \
+    $(TF_LITE_DIR)/downloads/neon_2_sse \
+    $(TF_LITE_DIR)/downloads/farmhash/src \
+    $(TF_LITE_DIR)/downloads/flatbuffers/include
+
+
+LOCAL_SRC_FILES := $(TFLITE_SRCS)
+LOCAL_C_INCLUDES := $(TFLITE_INCLUDES)
+
+LOCAL_CFLAGS += -O3 -DNDEBUG
+LOCAL_CXXFLAGS += -std=c++11 -frtti -fexceptions -O3 -DNDEBUG
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := nnstreamer_filter_tensorflow-lite
+LOCAL_SRC_FILES := $(NNSTREAMER_FILTER_TFLITE_SRCS)
+LOCAL_C_INCLUDES  := $(NNSTREAMER_INCLUDES) $(TFLITE_INCLUDES)
+
+LOCAL_SHARED_LIBRARIES := $(GST_BUILDING_BLOCK_LIST) nnstreamer
+LOCAL_STATIC_LIBRARIES := tensorflow-lite cpufeatures
+ifeq ($(ENABLE_NNAPI), true)
+LOCAL_SHARED_LIBRARIES += $(NNAPI_BUILDING_BLOCK)
+LOCAL_STATIC_LIBRARIES += $(NNAPI_BUILDING_BLOCK_STATIC)
+endif
+
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CXXFLAGS      += -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CFLAGS        += -pthread -fopenmp
+
+LOCAL_C_INCLUDES += $(GSTREAMER_ROOT)/include/gstreamer-1.0 \
+     $(GSTREAMER_ROOT)/include/glib-2.0 \
+     $(GSTREAMER_ROOT)/lib/glib-2.0/include \
+     $(GSTREAMER_ROOT)/include
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := nnstreamer_decoder_bounding_boxes
+LOCAL_SRC_FILES := $(NNSTREAMER_DECODER_BB_SRCS)
+LOCAL_C_INCLUDES    := $(NNSTREAMER_INCLUDES)
+
+LOCAL_SHARED_LIBRARIES := $(GST_BUILDING_BLOCK_LIST) nnstreamer
+
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -O0 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CXXFLAGS      += -std=c++11 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CFLAGS        += -pthread -fopenmp
+
+LOCAL_C_INCLUDES += $(GSTREAMER_ROOT)/include/gstreamer-1.0 \
+     $(GSTREAMER_ROOT)/include/glib-2.0 \
+     $(GSTREAMER_ROOT)/lib/glib-2.0/include \
+     $(GSTREAMER_ROOT)/include
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := nnstreamer_decoder_image_labeling
+LOCAL_SRC_FILES := $(NNSTREAMER_DECODER_IL_SRCS)
+LOCAL_C_INCLUDES    := $(NNSTREAMER_INCLUDES)
+
+LOCAL_SHARED_LIBRARIES := $(GST_BUILDING_BLOCK_LIST) nnstreamer
+
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -O0 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CXXFLAGS      += -std=c++11 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CFLAGS        += -pthread -fopenmp
+
+LOCAL_C_INCLUDES += $(GSTREAMER_ROOT)/include/gstreamer-1.0 \
+     $(GSTREAMER_ROOT)/include/glib-2.0 \
+     $(GSTREAMER_ROOT)/lib/glib-2.0/include \
+     $(GSTREAMER_ROOT)/include
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := nnstreamer_decoder_direct_video
+LOCAL_SRC_FILES := $(NNSTREAMER_DECODER_DV_SRCS)
+LOCAL_C_INCLUDES    := $(NNSTREAMER_INCLUDES)
+
+LOCAL_SHARED_LIBRARIES := $(GST_BUILDING_BLOCK_LIST) nnstreamer
+
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -O0 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CXXFLAGS      += -std=c++11 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CFLAGS        += -pthread -fopenmp
+
+LOCAL_C_INCLUDES += $(GSTREAMER_ROOT)/include/gstreamer-1.0 \
+     $(GSTREAMER_ROOT)/include/glib-2.0 \
+     $(GSTREAMER_ROOT)/lib/glib-2.0/include \
+     $(GSTREAMER_ROOT)/include
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := nnstreamer_decoder_pose_estimation
+LOCAL_SRC_FILES := $(NNSTREAMER_DECODER_PE_SRCS)
+LOCAL_C_INCLUDES    := $(NNSTREAMER_INCLUDES)
+
+LOCAL_SHARED_LIBRARIES := $(GST_BUILDING_BLOCK_LIST) nnstreamer
+
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -O0 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CXXFLAGS      += -std=c++11 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CFLAGS        += -pthread -fopenmp
+
+LOCAL_C_INCLUDES += $(GSTREAMER_ROOT)/include/gstreamer-1.0 \
+     $(GSTREAMER_ROOT)/include/glib-2.0 \
+     $(GSTREAMER_ROOT)/lib/glib-2.0/include \
+     $(GSTREAMER_ROOT)/include
+
+include $(BUILD_SHARED_LIBRARY)
+
+$(call import-module, android/cpufeatures)
index b7c59e8..48be275 100644 (file)
@@ -1,7 +1,8 @@
 # This mk file defines common features to build NNStreamer library for Android.
 
 ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
+$(warning NNSTREAMER_ROOT is not defined! Using $(LOCAL_PATH)/.. )
+NNSTREAMER_ROOT := $(LOCAL_PATH)/..
 endif
 
 NNSTREAMER_VERSION  := 0.2.1
@@ -87,3 +88,39 @@ NNSTREAMER_DECODER_PE_SRCS := \
 # common features
 NO_AUDIO := false
 
+ENABLE_NNAPI :=false
+
+GST_LIBS_COMMON := gstreamer-1.0 gstbase-1.0 gstvideo-1.0 glib-2.0 \
+                   gobject-2.0 intl z bz2 orc-0.4 gmodule-2.0 gsttag-1.0 iconv \
+                   gstapp-1.0 png16 gio-2.0 pangocairo-1.0 \
+                   pangoft2-1.0 pango-1.0 gthread-2.0 cairo pixman-1 fontconfig expat freetype \
+                   gstcontroller-1.0 jpeg graphene-1.0 gstpbutils-1.0 gstgl-1.0 \
+                   gstallocators-1.0 harfbuzz gstphotography-1.0 ffi fribidi gstnet-1.0 \
+                  cairo-gobject cairo-script-interpreter
+
+ifeq ($(NO_AUDIO), false)
+GST_LIBS_COMMON += gstaudio-1.0 gstbadaudio-1.0
+endif
+
+GST_LIBS_GST := gstcoreelements gstcoretracers gstadder gstapp \
+                gstpango gstrawparse gsttypefindfunctions gstvideoconvert gstvideorate \
+                gstvideoscale gstvideotestsrc gstvolume gstautodetect gstvideofilter gstvideocrop gstopengl \
+                gstopensles gstcompositor gstpng gstmultifile gstvideomixer gsttcp gstjpegformat gstcairo
+
+ifeq ($(NO_AUDIO), false)
+GST_LIBS_GST += gstaudioconvert gstaudiomixer gstaudiorate gstaudioresample gstaudiotestsrc gstjpeg
+endif
+
+# gstreamer building block for nstreamer
+GST_BUILDING_BLOCK_LIST := $(GST_LIBS_COMMON) $(GST_LIBS_GST)
+
+# gstreamer building block for decoder and filter
+NNSTREAMER_BUILDING_BLOCK_LIST := $(GST_BUILDING_BLOCK_LIST) nnstreamer nnstreamer_decoder_bounding_boxes nnstreamer_decoder_pose_estimation nnstreamer_filter_tensorflow-lite
+
+# libs for nnapi
+NNAPI_BUILDING_BLOCK := arm_compute_ex backend_acl_cl backend_acl_neon backend_cpu \
+                        neuralnetworks arm_compute_core arm_compute_graph arm_compute OpenCL
+
+ifeq ($(ENABLE_NNAPI), true)
+NNSTR$EAMER_BUILDING_BLOCK_LIST += $(NNAPI_BUILDING_BLOCK)
+endif
diff --git a/jni/prepare_tflite.sh b/jni/prepare_tflite.sh
new file mode 100755 (executable)
index 0000000..1a345ba
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+#currently we are using tensorflow 1.9.0
+VERSION="1.9.0"
+
+#Get tensorflow
+if [ ! -d "tensorflow-${VERSION}" ]; then
+    if [ ! -f "v${VERSION}.tar.gz" ]; then
+       echo "[TENSORFLOW-LITE] Download tensorflow-${VERSION}\n"
+       wget "https://github.com/tensorflow/tensorflow/archive/v${VERSION}.tar.gz"
+       echo "[TENSORFLOW-LITE] Finish Downloading tensorflow-${VERSION}\n"
+       echo "[TENSORFLOW-LITE] untar tensorflow-${VERSION}\n"
+    fi
+    tar xf "v${VERSION}.tar.gz"
+fi
+
+if [ ! -d "tensorflow-${VERSION}/tensorflow/contrib/lite/downloads" ]; then
+#Download Dependencys
+    pushd "tensorflow-${VERSION}"
+    echo "[TENSORFLOW-LITE] Download external libraries of tensorflow-${VERSION}\n"
+    sed -i "s|flatbuffers/archive/master.zip|flatbuffers/archive/v1.8.0.zip|g" tensorflow/contrib/lite/download_dependencies.sh
+    ./tensorflow/contrib/lite/download_dependencies.sh
+    popd
+fi