register custom-filter and amcsrc for native build.
Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
package org.nnsuite.nnstreamer;
+import android.os.Environment;
import android.support.test.rule.GrantPermissionRule;
import android.support.test.runner.AndroidJUnit4;
/* expected */
}
}
+
+ @Test
+ public void testAMCsrc() {
+ String root = Environment.getExternalStorageDirectory().getAbsolutePath();
+ String media = root + "/nnstreamer/test/test_video.mp4";
+
+ String desc = "amcsrc location=" + media + " ! " +
+ "videoconvert ! videoscale ! video/x-raw,format=RGB,width=320,height=240 ! " +
+ "tensor_converter ! tensor_sink name=sinkx";
+
+ try (Pipeline pipe = new Pipeline(desc)) {
+ /* 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, 230400)) {
+ mInvalidState = true;
+ }
+ }
+
+ mReceived++;
+ }
+ });
+
+ /* start pipeline */
+ pipe.start();
+
+ /* sleep 2 seconds to invoke */
+ Thread.sleep(2000);
+
+ /* stop pipeline */
+ pipe.stop();
+
+ /* check received data from sink */
+ assertFalse(mInvalidState);
+ assertTrue(mReceived > 0);
+
+ /* sleep 1 second and restart */
+ Thread.sleep(1000);
+ mReceived = 0;
+
+ pipe.start();
+
+ /* sleep 2 seconds to invoke */
+ Thread.sleep(2000);
+
+ /* stop pipeline */
+ pipe.stop();
+
+ /* check received data from sink */
+ assertFalse(mInvalidState);
+ assertTrue(mReceived > 0);
+ } catch (Exception e) {
+ fail();
+ }
+ }
}
$(NNSTREAMER_COMMON_SRCS) \
$(NNSTREAMER_PLUGINS_SRCS) \
$(NNSTREAMER_CAPI_SRCS) \
+ $(NNSTREAMER_SOURCE_AMC_SRCS) \
+ $(NNSTREAMER_FILTER_CPP_SRCS) \
$(NNSTREAMER_FILTER_TFLITE_SRCS) \
$(NNSTREAMER_DECODER_BB_SRCS) \
$(NNSTREAMER_DECODER_DV_SRCS) \
LOCAL_C_INCLUDES := $(NNSTREAMER_INCLUDES) $(NNSTREAMER_CAPI_INCLUDES)
LOCAL_STATIC_LIBRARIES := nnstreamer tensorflow-lite cpufeatures
LOCAL_SHARED_LIBRARIES := gstreamer_android
-LOCAL_LDLIBS := -llog -landroid
+LOCAL_LDLIBS := -llog -landroid -lmediandk
ifeq ($(ENABLE_SNAP), true)
LOCAL_CFLAGS += -DENABLE_SNAP=1
/* nnstreamer plugins and sub-plugins declaration */
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);
extern void init_is (void);
/**
+ * @brief Global lock for native functions.
+ */
+G_LOCK_DEFINE_STATIC (nns_native_lock);
+
+/**
* @brief Attach thread with Java VM.
*/
static JNIEnv *
jboolean
nnstreamer_native_initialize (void)
{
+ jboolean result = JNI_FALSE;
+ static gboolean nns_is_initilaized = FALSE;
+
nns_logi ("Called native initialize.");
+ G_LOCK (nns_native_lock);
+
if (!gst_is_initialized ()) {
nns_loge ("GStreamer is not initialized.");
- return JNI_FALSE;
+ goto done;
}
- /* register nnstreamer plugins */
- GST_PLUGIN_STATIC_REGISTER (nnstreamer);
+ if (nns_is_initilaized == FALSE) {
+ /* register nnstreamer plugins */
+ GST_PLUGIN_STATIC_REGISTER (nnstreamer);
- /* tensor-filter sub-plugin for tensorflow-lite */
- init_filter_tflite ();
+ /* Android MediaCodec */
+ GST_PLUGIN_STATIC_REGISTER (amcsrc);
+ /* tensor-filter sub-plugins */
+ init_filter_cpp ();
+ init_filter_custom ();
+ init_filter_custom_easy ();
+ init_filter_tflite ();
#if defined (ENABLE_SNAP)
- /* tensor-filter sub-plugin for snap */
- init_filter_snap ();
+ init_filter_snap ();
#endif
- /* tensor-decoder sub-plugins */
- init_dv ();
- init_bb ();
- init_il ();
- init_pose ();
- init_is ();
+ /* tensor-decoder sub-plugins */
+ init_dv ();
+ init_bb ();
+ init_il ();
+ init_pose ();
+ init_is ();
- return JNI_TRUE;
+ nns_is_initilaized = TRUE;
+ }
+
+ result = JNI_TRUE;
+
+done:
+ G_UNLOCK (nns_native_lock);
+ return result;
}
/**
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.h main/jni/nnstreamer/include
nnstreamer_native_files="$nnstreamer_lib_name-native-$today.zip"
zip -r $nnstreamer_native_files main
#include "tensor_filter_cpp.h"
-void init_filter_cpp (void) __attribute__ ((constructor));
-void fini_filter_cpp (void) __attribute__ ((destructor));
-
std::unordered_map<std::string, tensor_filter_cpp*> tensor_filter_cpp::filters;
static gchar filter_subplugin_cpp[] = "cpp";
cpp->ref_count--;
}
+G_BEGIN_DECLS
+void init_filter_cpp (void) __attribute__ ((constructor));
+void fini_filter_cpp (void) __attribute__ ((destructor));
+
/** @brief Initialize this object for tensor_filter subplugin runtime register */
void
init_filter_cpp (void)
{
nnstreamer_filter_exit (NNS_support_cpp.name);
}
+G_END_DECLS
#include "nnstreamer_plugin_api_filter.h"
#include "nnstreamer_conf.h"
-static void init_filter_custom (void) __attribute__ ((constructor));
-static void fini_filter_custom (void) __attribute__ ((destructor));
+void init_filter_custom (void) __attribute__ ((constructor));
+void fini_filter_custom (void) __attribute__ ((destructor));
static GstTensorFilterFramework NNS_support_custom;
};
/** @brief Initialize this object for tensor_filter subplugin runtime register */
-static void
+void
init_filter_custom (void)
{
nnstreamer_filter_probe (&NNS_support_custom);
}
/** @brief Destruct the subplugin */
-static void
+void
fini_filter_custom (void)
{
nnstreamer_filter_exit (NNS_support_custom.name);
#include <nnstreamer_plugin_api.h>
#include <nnstreamer_subplugin.h>
-static void init_filter_custom (void) __attribute__ ((constructor));
-static void fini_filter_custom (void) __attribute__ ((destructor));
+void init_filter_custom_easy (void) __attribute__ ((constructor));
+void fini_filter_custom_easy (void) __attribute__ ((destructor));
/**
* @brief internal_data
};
/** @brief Initialize this object for tensor_filter subplugin runtime register */
-static void
-init_filter_custom (void)
+void
+init_filter_custom_easy (void)
{
nnstreamer_filter_probe (&NNS_support_custom_easy);
}
/** @brief Destruct the subplugin */
-static void
-fini_filter_custom (void)
+void
+fini_filter_custom_easy (void)
{
nnstreamer_filter_exit (NNS_support_custom_easy.name);
}
$(NNSTREAMER_GST_HOME)/tensor_filter/tensor_filter.c \
$(NNSTREAMER_GST_HOME)/tensor_filter/tensor_filter_common.c \
$(NNSTREAMER_GST_HOME)/tensor_filter/tensor_filter_custom.c \
+ $(NNSTREAMER_GST_HOME)/tensor_filter/tensor_filter_custom_easy.c \
$(NNSTREAMER_GST_HOME)/tensor_merge/gsttensormerge.c \
$(NNSTREAMER_GST_HOME)/tensor_mux/gsttensormux.c \
$(NNSTREAMER_GST_HOME)/tensor_repo/tensor_repo.c \
$(NNSTREAMER_CAPI_HOME)/src/nnstreamer-capi-util.c \
$(NNSTREAMER_CAPI_HOME)/src/tensor_filter_single.c
+# source AMC (Android MediaCodec)
+NNSTREAMER_SOURCE_AMC_SRCS := \
+ $(NNSTREAMER_EXT_HOME)/android_source/gstamcsrc.c \
+ $(NNSTREAMER_EXT_HOME)/android_source/gstamcsrc_looper.cc
+
+# filter cpp
+NNSTREAMER_FILTER_CPP_SRCS := \
+ $(NNSTREAMER_EXT_HOME)/tensor_filter/tensor_filter_cpp.cc
+
# filter tensorflow
NNSTREAMER_FILTER_TF_SRCS := \
$(NNSTREAMER_EXT_HOME)/tensor_filter/tensor_filter_tensorflow.cc