[Android] prepare single-only build
authorJaeyun <jy1210.jung@samsung.com>
Wed, 12 Feb 2020 11:20:18 +0000 (20:20 +0900)
committerwooksong <wook16.song@samsung.com>
Fri, 28 Feb 2020 05:46:45 +0000 (14:46 +0900)
With the request to build single-shot only library, add definition and  update build script.

Signed-off-by: Jaeyun <jy1210.jung@samsung.com>
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCommon.java
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestPipeline.java
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestSNAP.java [deleted file]
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestSingleShot.java
api/android/api/src/main/jni/Android-gst-plugins.mk
api/android/api/src/main/jni/Android-nnstreamer.mk
api/android/api/src/main/jni/Android.mk
api/android/api/src/main/jni/nnstreamer-native-api.c
api/android/build-android-lib.sh
gst/nnstreamer/tensor_common.c
jni/nnstreamer.mk

index 9462135..fafd1fc 100644 (file)
@@ -66,6 +66,41 @@ public class APITestCommon {
     }
 
     /**
+     * Gets the File objects of Caffe model for SNAP.
+     */
+    public static File[] getSNAPCaffeModel() {
+        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
+
+        File model = new File(root + "/nnstreamer/snap_data/prototxt/squeezenet.prototxt");
+        File weight = new File(root + "/nnstreamer/snap_data/model/squeezenet.caffemodel");
+
+        if (!model.exists() || !weight.exists()) {
+            fail();
+        }
+
+        return new File[]{model, weight};
+    }
+
+    /**
+     * Gets the option string to run Caffe model for SNAP.
+     *
+     * CPU: "custom=ModelFWType:CAFFE,ExecutionDataType:FLOAT32,ComputingUnit:CPU"
+     * GPU: "custom=ModelFWType:CAFFE,ExecutionDataType:FLOAT32,ComputingUnit:GPU,GpuCacheSource:/sdcard/nnstreamer/"
+     */
+    public static String getSNAPCaffeOption(boolean useGPU) {
+        String option = "ModelFWType:CAFFE,ExecutionDataType:FLOAT32,";
+
+        if (useGPU) {
+            String root = Environment.getExternalStorageDirectory().getAbsolutePath();
+            option = option + "ComputingUnit:GPU,GpuCacheSource:" + root + "/nnstreamer/";
+        } else {
+            option = option + "ComputingUnit:CPU";
+        }
+
+        return option;
+    }
+
+    /**
      * Verifies the byte buffer is direct buffer with native order.
      *
      * @param buffer   The byte buffer
index 6eb9d4b..278e5db 100644 (file)
@@ -820,4 +820,90 @@ public class APITestPipeline {
             fail();
         }
     }
+
+    /**
+     * Run SNAP with Caffe model.
+     */
+    private void runSNAPCaffe(boolean useGPU) {
+        File[] models = APITestCommon.getSNAPCaffeModel();
+        String option = APITestCommon.getSNAPCaffeOption(useGPU);
+
+        String desc = "appsrc name=srcx ! " +
+                "other/tensor,dimension=(string)3:224:224:1,type=(string)float32,framerate=(fraction)0/1 ! " +
+                "tensor_filter framework=snap " +
+                    "model=" + models[0].getAbsolutePath() + "," + models[1].getAbsolutePath() + " " +
+                    "input=3:224:224:1 inputtype=float32 inputlayout=NHWC inputname=data " +
+                    "output=1:1:1000:1 outputtype=float32 outputlayout=NCHW outputname=prob " +
+                    "custom=" + option + " ! " +
+                "tensor_sink name=sinkx";
+
+        try (Pipeline pipe = new Pipeline(desc)) {
+            TensorsInfo info = new TensorsInfo();
+            info.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{3,224,224,1});
+
+            /* register sink callback */
+            pipe.registerSinkCallback("sinkx", new Pipeline.NewDataCallback() {
+                @Override
+                public void onNewDataReceived(TensorsData data) {
+                    if (data == null || data.getTensorsCount() != 1) {
+                        mInvalidState = true;
+                        return;
+                    }
+
+                    TensorsInfo info = data.getTensorsInfo();
+
+                    if (info == null || info.getTensorsCount() != 1) {
+                        mInvalidState = true;
+                    } else {
+                        ByteBuffer output = data.getTensorData(0);
+
+                        if (!APITestCommon.isValidBuffer(output, 4000)) {
+                            mInvalidState = true;
+                        }
+                    }
+
+                    mReceived++;
+                }
+            });
+
+            /* start pipeline */
+            pipe.start();
+
+            /* push input buffer */
+            for (int i = 0; i < 10; i++) {
+                /* dummy input */
+                pipe.inputData("srcx", TensorsData.allocate(info));
+                Thread.sleep(100);
+            }
+
+            /* sleep 500 to invoke */
+            Thread.sleep(500);
+
+            /* check received data from sink */
+            assertFalse(mInvalidState);
+            assertTrue(mReceived > 0);
+        } catch (Exception e) {
+            fail();
+        }
+    }
+
+    @Test
+    public void testSNAPCaffeCPU() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
+            /* cannot run the test */
+            return;
+        }
+
+        runSNAPCaffe(false);
+    }
+
+    @Test
+    public void testSNAPCaffeGPU() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
+            /* cannot run the test */
+            return;
+        }
+
+        runSNAPCaffe(true);
+    }
 }
diff --git a/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestSNAP.java b/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestSNAP.java
deleted file mode 100644 (file)
index e3623e6..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-package org.nnsuite.nnstreamer;
-
-import android.os.Environment;
-import android.support.test.rule.GrantPermissionRule;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-
-import static org.junit.Assert.*;
-
-/**
- * Testcases for the filter sub-plugin SNAP.
- * Note that, it takes a time with GPU option in the first run.
- */
-@RunWith(AndroidJUnit4.class)
-public class APITestSNAP {
-    private int mReceived = 0;
-    private boolean mInvalidState = false;
-    private boolean mIsAvailable = false;
-
-    /**
-     * Gets the File objects of SNAP Caffe model.
-     */
-    private File[] getCaffeModel() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-
-        File model = new File(root + "/nnstreamer/snap_data/prototxt/squeezenet.prototxt");
-        File weight = new File(root + "/nnstreamer/snap_data/model/squeezenet.caffemodel");
-
-        if (!model.exists() || !weight.exists()) {
-            fail();
-        }
-
-        return new File[]{model, weight};
-    }
-
-    /**
-     * Gets the option string to run Caffe model.
-     *
-     * CPU: "custom=ModelFWType:CAFFE,ExecutionDataType:FLOAT32,ComputingUnit:CPU"
-     * GPU: "custom=ModelFWType:CAFFE,ExecutionDataType:FLOAT32,ComputingUnit:GPU,GpuCacheSource:/sdcard/nnstreamer/"
-     */
-    private String getCaffeOption(boolean useGPU) {
-        String option = "ModelFWType:CAFFE,ExecutionDataType:FLOAT32,";
-
-        if (useGPU) {
-            String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-            option = option + "ComputingUnit:GPU,GpuCacheSource:" + root + "/nnstreamer/";
-        } else {
-            option = option + "ComputingUnit:CPU";
-        }
-
-        return option;
-    }
-
-    /**
-     * SingleShot with option string.
-     */
-    private void runSingleShotCaffe(boolean useGPU) {
-        File[] models = getCaffeModel();
-        String option = getCaffeOption(useGPU);
-
-        try {
-            TensorsInfo in = new TensorsInfo();
-            in.addTensorInfo("data", NNStreamer.TensorType.FLOAT32, new int[]{3,224,224,1});
-
-            TensorsInfo out = new TensorsInfo();
-            out.addTensorInfo("prob", NNStreamer.TensorType.FLOAT32, new int[]{1,1,1000,1});
-
-            SingleShot single = new SingleShot(models, in, out, NNStreamer.NNFWType.SNAP, option);
-
-            /* let's ignore timeout (set 60 sec) */
-            single.setTimeout(60000);
-
-            /* set layout */
-            single.setProperty("inputlayout", "NHWC");
-            single.setProperty("outputlayout", "NCHW");
-
-            /* single-shot invoke */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                TensorsData output = single.invoke(in.allocate());
-
-                /* output: float32 1:1:1000:1 (NCHW format) */
-                assertEquals(1, output.getTensorsCount());
-                assertEquals(4000, output.getTensorData(0).capacity());
-
-                Thread.sleep(30);
-            }
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    /**
-     * Pipeline with option string.
-     */
-    private void runPipelineCaffe(boolean useGPU) {
-        File[] models = getCaffeModel();
-        String option = getCaffeOption(useGPU);
-
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)3:224:224:1,type=(string)float32,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=snap " +
-                    "model=" + models[0].getAbsolutePath() + "," + models[1].getAbsolutePath() + " " +
-                    "input=3:224:224:1 inputtype=float32 inputlayout=NHWC inputname=data " +
-                    "output=1:1:1000:1 outputtype=float32 outputlayout=NCHW outputname=prob " +
-                    "custom=" + option + " ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{3,224,224,1});
-
-            /* register sink callback */
-            pipe.registerSinkCallback("sinkx", new Pipeline.NewDataCallback() {
-                @Override
-                public void onNewDataReceived(TensorsData data) {
-                    if (data == null || data.getTensorsCount() != 1) {
-                        mInvalidState = true;
-                        return;
-                    }
-
-                    TensorsInfo info = data.getTensorsInfo();
-
-                    if (info == null || info.getTensorsCount() != 1) {
-                        mInvalidState = true;
-                    } else {
-                        ByteBuffer output = data.getTensorData(0);
-
-                        if (!APITestCommon.isValidBuffer(output, 4000)) {
-                            mInvalidState = true;
-                        }
-                    }
-
-                    mReceived++;
-                }
-            });
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", TensorsData.allocate(info));
-                Thread.sleep(100);
-            }
-
-            /* sleep 500 to invoke */
-            Thread.sleep(500);
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Rule
-    public GrantPermissionRule mPermissionRule = APITestCommon.grantPermissions();
-
-    @Before
-    public void setUp() {
-        APITestCommon.initNNStreamer();
-
-        mReceived = 0;
-        mInvalidState = false;
-        mIsAvailable = NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP);
-    }
-
-    @Test
-    public void testRunSingleCaffeCPU() {
-        if (!mIsAvailable) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSingleShotCaffe(false);
-    }
-
-    @Test
-    public void testRunSingleCaffeGPU() {
-        if (!mIsAvailable) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSingleShotCaffe(true);
-    }
-
-    @Test
-    public void testRunPipelineCaffeCPU() {
-        if (!mIsAvailable) {
-            /* cannot run the test */
-            return;
-        }
-
-        runPipelineCaffe(false);
-    }
-
-    @Test
-    public void testRunPipelineCaffeGPU() {
-        if (!mIsAvailable) {
-            /* cannot run the test */
-            return;
-        }
-
-        runPipelineCaffe(true);
-    }
-}
index 6308657..ae0100c 100644 (file)
@@ -390,4 +390,63 @@ public class APITestSingleShot {
             fail();
         }
     }
+
+    /**
+     * Run SNAP with Caffe model.
+     */
+    private void runSNAPCaffe(boolean useGPU) {
+        File[] models = APITestCommon.getSNAPCaffeModel();
+        String option = APITestCommon.getSNAPCaffeOption(useGPU);
+
+        try {
+            TensorsInfo in = new TensorsInfo();
+            in.addTensorInfo("data", NNStreamer.TensorType.FLOAT32, new int[]{3,224,224,1});
+
+            TensorsInfo out = new TensorsInfo();
+            out.addTensorInfo("prob", NNStreamer.TensorType.FLOAT32, new int[]{1,1,1000,1});
+
+            SingleShot single = new SingleShot(models, in, out, NNStreamer.NNFWType.SNAP, option);
+
+            /* let's ignore timeout (set 60 sec) */
+            single.setTimeout(60000);
+
+            /* set layout */
+            single.setProperty("inputlayout", "NHWC");
+            single.setProperty("outputlayout", "NCHW");
+
+            /* single-shot invoke */
+            for (int i = 0; i < 10; i++) {
+                /* dummy input */
+                TensorsData output = single.invoke(in.allocate());
+
+                /* output: float32 1:1:1000:1 (NCHW format) */
+                assertEquals(1, output.getTensorsCount());
+                assertEquals(4000, output.getTensorData(0).capacity());
+
+                Thread.sleep(30);
+            }
+        } catch (Exception e) {
+            fail();
+        }
+    }
+
+    @Test
+    public void testSNAPCaffeCPU() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
+            /* cannot run the test */
+            return;
+        }
+
+        runSNAPCaffe(false);
+    }
+
+    @Test
+    public void testSNAPCaffeGPU() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
+            /* cannot run the test */
+            return;
+        }
+
+        runSNAPCaffe(true);
+    }
 }
index c9cca9a..e778193 100644 (file)
@@ -27,12 +27,16 @@ GST_REQUIRED_PLUGINS := $(GSTREAMER_PLUGINS_CORE) \
     $(GSTREAMER_PLUGINS_NET_RESTRICTED) \
     $(GSTREAMER_PLUGINS_GES)
 GST_REQUIRED_DEPS := gstreamer-video-1.0 gstreamer-audio-1.0 gstreamer-app-1.0
-GST_REQUIRED_LIBS := -liconv
+GST_REQUIRED_LIBS :=
 else ifeq ($(NNSTREAMER_API_OPTION),lite)
 # Build with core plugins
 GST_REQUIRED_PLUGINS := $(GSTREAMER_PLUGINS_CORE)
 GST_REQUIRED_DEPS := gstreamer-video-1.0 gstreamer-audio-1.0 gstreamer-app-1.0
-GST_REQUIRED_LIBS := -liconv
+GST_REQUIRED_LIBS :=
+else ifeq ($(NNSTREAMER_API_OPTION),single)
+GST_REQUIRED_PLUGINS :=
+GST_REQUIRED_DEPS :=
+GST_REQUIRED_LIBS :=
 else
 $(error Unknown build option: $(NNSTREAMER_API_OPTION))
 endif
index d2ee946..7ee0141 100644 (file)
@@ -13,10 +13,23 @@ endif
 
 include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
 
+NNSTREAMER_FLAGS := -DVERSION=\"$(NNSTREAMER_VERSION)\"
+
 NNSTREAMER_SRC_FILES := \
-    $(NNSTREAMER_COMMON_SRCS) \
-    $(NNSTREAMER_PLUGINS_SRCS) \
+    $(NNSTREAMER_COMMON_SRCS)
+
+ifeq ($(NNSTREAMER_API_OPTION),single)
+# single-shot with tf-lite
+NNSTREAMER_SRC_FILES += \
+    $(NNSTREAMER_SINGLE_SRCS) \
+    $(NNSTREAMER_FILTER_TFLITE_SRCS)
+
+NNSTREAMER_FLAGS += -DNNS_SINGLE_ONLY=1
+else
+# capi and nnstreamer plugins
+NNSTREAMER_SRC_FILES += \
     $(NNSTREAMER_CAPI_SRCS) \
+    $(NNSTREAMER_PLUGINS_SRCS) \
     $(NNSTREAMER_SOURCE_AMC_SRCS) \
     $(NNSTREAMER_FILTER_CPP_SRCS) \
     $(NNSTREAMER_FILTER_TFLITE_SRCS) \
@@ -25,6 +38,7 @@ NNSTREAMER_SRC_FILES := \
     $(NNSTREAMER_DECODER_IL_SRCS) \
     $(NNSTREAMER_DECODER_PE_SRCS) \
     $(NNSTREAMER_DECODER_IS_SRCS)
+endif
 
 # Remove duplicates
 LOCAL_SRC_FILES := $(sort $(NNSTREAMER_SRC_FILES))
@@ -39,7 +53,7 @@ LOCAL_C_INCLUDES += $(GST_HEADERS_COMMON)
 # common headers (tensorflow-lite)
 LOCAL_C_INCLUDES += $(TF_LITE_INCLUDES)
 
-LOCAL_CFLAGS += -O2 -DVERSION=\"$(NNSTREAMER_VERSION)\"
-LOCAL_CXXFLAGS += -std=c++11 -O2 -DVERSION=\"$(NNSTREAMER_VERSION)\"
+LOCAL_CFLAGS += -O2 $(NNSTREAMER_FLAGS)
+LOCAL_CXXFLAGS += -std=c++11 -O2 $(NNSTREAMER_FLAGS)
 
 include $(BUILD_STATIC_LIBRARY)
index 5554b34..b72e71d 100644 (file)
@@ -45,8 +45,6 @@ include $(CLEAR_VARS)
 
 LOCAL_MODULE := nnstreamer-native
 LOCAL_SRC_FILES := nnstreamer-native-api.c \
-    nnstreamer-native-customfilter.c \
-    nnstreamer-native-pipeline.c \
     nnstreamer-native-singleshot.c
 LOCAL_CFLAGS += -O2 -DVERSION=\"$(NNSTREAMER_VERSION)\"
 LOCAL_C_INCLUDES := $(NNSTREAMER_INCLUDES) $(NNSTREAMER_CAPI_INCLUDES)
@@ -54,6 +52,14 @@ LOCAL_STATIC_LIBRARIES := nnstreamer tensorflow-lite cpufeatures
 LOCAL_SHARED_LIBRARIES := gstreamer_android
 LOCAL_LDLIBS := -llog -landroid -lmediandk
 
+ifeq ($(NNSTREAMER_API_OPTION),single)
+LOCAL_CFLAGS += -DNNS_SINGLE_ONLY=1
+else
+LOCAL_SRC_FILES += \
+    nnstreamer-native-customfilter.c \
+    nnstreamer-native-pipeline.c
+endif
+
 ifeq ($(ENABLE_SNAP), true)
 LOCAL_CFLAGS += -DENABLE_SNAP=1
 LOCAL_STATIC_LIBRARIES += snap
@@ -68,8 +74,12 @@ GSTREAMER_NDK_BUILD_PATH := $(GSTREAMER_ROOT)/share/gst-android/ndk-build/
 include $(LOCAL_PATH)/Android-gst-plugins.mk
 
 GSTREAMER_PLUGINS        := $(GST_REQUIRED_PLUGINS)
-GSTREAMER_EXTRA_DEPS     := $(GST_REQUIRED_DEPS)
-GSTREAMER_EXTRA_LIBS     := $(GST_REQUIRED_LIBS)
+GSTREAMER_EXTRA_DEPS     := $(GST_REQUIRED_DEPS) gio-2.0
+GSTREAMER_EXTRA_LIBS     := $(GST_REQUIRED_LIBS) -liconv
+
+GSTREAMER_INCLUDE_FONTS := no
+GSTREAMER_INCLUDE_CA_CERTIFICATES := no
+
 include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer-1.0.mk
 
 $(call import-module, android/cpufeatures)
index 8b1ea6e..04b7e8d 100644 (file)
 #include "nnstreamer-native.h"
 
 /* nnstreamer plugins and sub-plugins declaration */
+#if !defined (NNS_SINGLE_ONLY)
 GST_PLUGIN_STATIC_DECLARE (nnstreamer);
 GST_PLUGIN_STATIC_DECLARE (amcsrc);
 extern void init_filter_cpp (void);
 extern void init_filter_custom (void);
 extern void init_filter_custom_easy (void);
 extern void init_filter_tflite (void);
-#if defined (ENABLE_SNAP)
-extern void init_filter_snap (void);
-#endif
 extern void init_dv (void);
 extern void init_bb (void);
 extern void init_il (void);
 extern void init_pose (void);
 extern void init_is (void);
+#endif
+
+extern void init_filter_tflite (void);
+#if defined (ENABLE_SNAP)
+extern void init_filter_snap (void);
+#endif
 
 /**
  * @brief Global lock for native functions.
@@ -97,6 +101,7 @@ nns_free_element_data (gpointer data)
 
   if (item) {
     switch (item->type) {
+#if !defined (NNS_SINGLE_ONLY)
       case NNS_ELEMENT_TYPE_SRC:
         ml_pipeline_src_release_handle ((ml_pipeline_src_h) item->handle);
         break;
@@ -110,6 +115,7 @@ nns_free_element_data (gpointer data)
       case NNS_ELEMENT_TYPE_SWITCH_OUT:
         ml_pipeline_switch_release_handle ((ml_pipeline_switch_h) item->handle);
         break;
+#endif
       default:
         nns_logw ("Given element type %d is unknown.", item->type);
         if (item->handle)
@@ -171,18 +177,20 @@ nns_destroy_pipe_info (pipeline_info_s * pipe_info, JNIEnv * env)
   g_mutex_unlock (&pipe_info->lock);
 
   switch (pipe_info->pipeline_type) {
+#if !defined (NNS_SINGLE_ONLY)
     case NNS_PIPE_TYPE_PIPELINE:
       ml_pipeline_destroy (pipe_info->pipeline_handle);
       break;
-    case NNS_PIPE_TYPE_SINGLE:
-      ml_single_close (pipe_info->pipeline_handle);
-      break;
     case NNS_PIPE_TYPE_CUSTOM:
       /**
        * Do nothing here (no handle to close).
        * The handle is filter-framework and it will be closed in customfilter-destroy function.
        */
       break;
+#endif
+    case NNS_PIPE_TYPE_SINGLE:
+      ml_single_close (pipe_info->pipeline_handle);
+      break;
     default:
       nns_logw ("Given pipe type %d is unknown.", pipe_info->pipeline_type);
       if (pipe_info->pipeline_handle)
@@ -585,6 +593,7 @@ nnstreamer_native_initialize (void)
 
   if (nns_is_initilaized == FALSE) {
     /* register nnstreamer plugins */
+#if !defined (NNS_SINGLE_ONLY)
     GST_PLUGIN_STATIC_REGISTER (nnstreamer);
 
     /* Android MediaCodec */
@@ -594,10 +603,6 @@ nnstreamer_native_initialize (void)
     init_filter_cpp ();
     init_filter_custom ();
     init_filter_custom_easy ();
-    init_filter_tflite ();
-#if defined (ENABLE_SNAP)
-    init_filter_snap ();
-#endif
 
     /* tensor-decoder sub-plugins */
     init_dv ();
@@ -605,6 +610,12 @@ nnstreamer_native_initialize (void)
     init_il ();
     init_pose ();
     init_is ();
+#endif
+
+    init_filter_tflite ();
+#if defined (ENABLE_SNAP)
+    init_filter_snap ();
+#endif
 
     nns_is_initilaized = TRUE;
   }
index f389ee3..8064405 100644 (file)
 #
 
 # API build option ('lite' to build with GStreamer core plugins)
-nnstreamer_api_option=all
+nnstreamer_api_option='all'
+include_assets='no'
 
 # Set target ABI ('armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64')
 nnstreamer_target_abi="'armeabi-v7a', 'arm64-v8a'"
 
 # Set tensorflow-lite version (available: 1.9 and 1.13)
-nnstreamer_tf_lite_ver=1.13
+nnstreamer_tf_lite_ver='1.13'
 
 # Run instrumentation test after build procedure is done
 run_test='no'
@@ -80,6 +81,14 @@ for arg in "$@"; do
     esac
 done
 
+# Check build option
+if [[ $nnstreamer_api_option == 'internal' ]]; then
+    # Enable SNAP and include single-shot only
+    nnstreamer_api_option='single'
+    include_assets='no'
+    enable_snap='yes'
+fi
+
 if [[ $enable_snap == 'yes' ]]; then
     [ -z "$SNAP_DIRECTORY" ] && echo "Need to set SNAP_DIRECTORY, to build sub-plugin for SNAP." && exit 1
 
@@ -159,6 +168,11 @@ sed -i "s|abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'|abiFilters $nns
 # Update API build option
 sed -i "s|NNSTREAMER_API_OPTION := all|NNSTREAMER_API_OPTION := $nnstreamer_api_option|" api/src/main/jni/Android.mk
 
+if [[ $include_assets == 'yes' ]]; then
+    sed -i "s|GSTREAMER_INCLUDE_FONTS := no|GSTREAMER_INCLUDE_FONTS := yes|" api/src/main/jni/Android.mk
+    sed -i "s|GSTREAMER_INCLUDE_CA_CERTIFICATES := no|GSTREAMER_INCLUDE_CA_CERTIFICATES := yes|" api/src/main/jni/Android.mk
+fi
+
 # Update SNAP option
 if [[ $enable_snap == 'yes' ]]; then
     sed -i "s|ENABLE_SNAP := false|ENABLE_SNAP := true|" ext-files/jni/Android-nnstreamer-prebuilt.mk
@@ -185,6 +199,14 @@ publish {\n\
 }|" api/build.gradle
 fi
 
+# If build option is single-shot only, remove unnecessary files.
+if [[ $nnstreamer_api_option == 'single' ]]; then
+    rm ./api/src/main/java/org/nnsuite/nnstreamer/CustomFilter.java
+    rm ./api/src/main/java/org/nnsuite/nnstreamer/Pipeline.java
+    rm ./api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCustomFilter.java
+    rm ./api/src/androidTest/java/org/nnsuite/nnstreamer/APITestPipeline.java
+fi
+
 echo "Starting gradle build for Android library."
 
 chmod +x gradlew
@@ -209,28 +231,35 @@ if [[ -e $nnstreamer_android_api_lib ]]; then
     # Prepare native libraries and header files for C-API
     unzip $nnstreamer_android_api_lib -d aar_extracted
 
-    mkdir -p main/assets
     mkdir -p main/java/org/freedesktop
     mkdir -p main/jni/nnstreamer/lib
     mkdir -p main/jni/nnstreamer/include
 
+    # assets
+    if [[ $include_assets == 'yes' ]]; then
+        mkdir -p main/assets
+        cp -r aar_extracted/assets/* main/assets
+    fi
+
     cp -r api/src/main/java/org/freedesktop/* main/java/org/freedesktop
-    cp -r aar_extracted/assets/* main/assets
     cp -r aar_extracted/jni/* main/jni/nnstreamer/lib
     cp ext-files/jni/Android-nnstreamer-prebuilt.mk main/jni
     # header for C-API
     cp $NNSTREAMER_ROOT/api/capi/include/nnstreamer.h main/jni/nnstreamer/include
     cp $NNSTREAMER_ROOT/api/capi/include/nnstreamer-single.h main/jni/nnstreamer/include
     cp $NNSTREAMER_ROOT/api/capi/include/platform/tizen_error.h main/jni/nnstreamer/include
+
     # header for plugin
-    cp $NNSTREAMER_ROOT/gst/nnstreamer/nnstreamer_plugin_api.h main/jni/nnstreamer/include
-    cp $NNSTREAMER_ROOT/gst/nnstreamer/nnstreamer_plugin_api_converter.h main/jni/nnstreamer/include
-    cp $NNSTREAMER_ROOT/gst/nnstreamer/nnstreamer_plugin_api_decoder.h main/jni/nnstreamer/include
-    cp $NNSTREAMER_ROOT/gst/nnstreamer/nnstreamer_plugin_api_filter.h main/jni/nnstreamer/include
-    cp $NNSTREAMER_ROOT/gst/nnstreamer/tensor_filter_custom.h main/jni/nnstreamer/include
-    cp $NNSTREAMER_ROOT/gst/nnstreamer/tensor_filter_custom_easy.h main/jni/nnstreamer/include
-    cp $NNSTREAMER_ROOT/gst/nnstreamer/tensor_typedef.h main/jni/nnstreamer/include
-    cp $NNSTREAMER_ROOT/ext/nnstreamer/tensor_filter/tensor_filter_cpp.hh main/jni/nnstreamer/include
+    if [[ $nnstreamer_api_option != 'single' ]]; then
+        cp $NNSTREAMER_ROOT/gst/nnstreamer/nnstreamer_plugin_api.h main/jni/nnstreamer/include
+        cp $NNSTREAMER_ROOT/gst/nnstreamer/nnstreamer_plugin_api_converter.h main/jni/nnstreamer/include
+        cp $NNSTREAMER_ROOT/gst/nnstreamer/nnstreamer_plugin_api_decoder.h main/jni/nnstreamer/include
+        cp $NNSTREAMER_ROOT/gst/nnstreamer/nnstreamer_plugin_api_filter.h main/jni/nnstreamer/include
+        cp $NNSTREAMER_ROOT/gst/nnstreamer/tensor_filter_custom.h main/jni/nnstreamer/include
+        cp $NNSTREAMER_ROOT/gst/nnstreamer/tensor_filter_custom_easy.h main/jni/nnstreamer/include
+        cp $NNSTREAMER_ROOT/gst/nnstreamer/tensor_typedef.h main/jni/nnstreamer/include
+        cp $NNSTREAMER_ROOT/ext/nnstreamer/tensor_filter/tensor_filter_cpp.hh main/jni/nnstreamer/include
+    fi
 
     nnstreamer_native_files="$nnstreamer_lib_name-native-$today.zip"
     zip -r $nnstreamer_native_files main
index b61952e..a573184 100644 (file)
@@ -1171,6 +1171,7 @@ replace_string (gchar * source, const gchar * what, const gchar * to,
   return result;
 }
 
+#if !defined (NNS_SINGLE_ONLY) /** @todo remove this definition (android release) */
 static const gchar *gst_tensor_time_sync_mode_string[] = {
   [SYNC_NOSYNC] = "nosync",
   [SYNC_SLOWEST] = "slowest",
@@ -1457,7 +1458,7 @@ gst_tensor_time_sync_buffer_from_collectpad (GstCollectPads * collect,
   /* not eos */
   return FALSE;
 }
-
+#endif
 /**
  * @brief Get the version of NNStreamer.
  * @return Newly allocated string. The returned string should be freed with g_free().
index 05a4b39..f5a8466 100644 (file)
@@ -20,13 +20,13 @@ NNSTREAMER_INCLUDES := \
 
 # nnstreamer common sources
 NNSTREAMER_COMMON_SRCS := \
-    $(NNSTREAMER_GST_HOME)/nnstreamer.c \
     $(NNSTREAMER_GST_HOME)/nnstreamer_conf.c \
     $(NNSTREAMER_GST_HOME)/nnstreamer_subplugin.c \
     $(NNSTREAMER_GST_HOME)/tensor_common.c
 
 # nnstreamer plugins
 NNSTREAMER_PLUGINS_SRCS := \
+    $(NNSTREAMER_GST_HOME)/nnstreamer.c \
     $(NNSTREAMER_GST_HOME)/tensor_converter/tensor_converter.c \
     $(NNSTREAMER_GST_HOME)/tensor_aggregator/tensor_aggregator.c \
     $(NNSTREAMER_GST_HOME)/tensor_decoder/tensordec.c \
@@ -56,6 +56,13 @@ NNSTREAMER_CAPI_SRCS := \
     $(NNSTREAMER_CAPI_HOME)/src/nnstreamer-capi-util.c \
     $(NNSTREAMER_CAPI_HOME)/src/tensor_filter_single.c
 
+# nnstreamer c-api for single-shot only
+NNSTREAMER_SINGLE_SRCS := \
+    $(NNSTREAMER_CAPI_HOME)/src/nnstreamer-capi-single.c \
+    $(NNSTREAMER_CAPI_HOME)/src/nnstreamer-capi-util.c \
+    $(NNSTREAMER_CAPI_HOME)/src/tensor_filter_single.c \
+    $(NNSTREAMER_GST_HOME)/tensor_filter/tensor_filter_common.c
+
 # source AMC (Android MediaCodec)
 NNSTREAMER_SOURCE_AMC_SRCS := \
     $(NNSTREAMER_EXT_HOME)/android_source/gstamcsrc.c \