From: Jaeyun Date: Tue, 14 Jan 2020 11:31:28 +0000 (+0900) Subject: [Android] custom-filter and amcsrc for native build X-Git-Tag: accepted/tizen/unified/20200130.214603~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0189ecacf9e851e7420bdce6130f7060016a0cb2;p=platform%2Fupstream%2Fnnstreamer.git [Android] custom-filter and amcsrc for native build register custom-filter and amcsrc for native build. Signed-off-by: Jaeyun Jung --- diff --git a/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestPipeline.java b/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestPipeline.java index 6c88d93..6eb9d4b 100644 --- a/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestPipeline.java +++ b/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestPipeline.java @@ -1,5 +1,6 @@ package org.nnsuite.nnstreamer; +import android.os.Environment; import android.support.test.rule.GrantPermissionRule; import android.support.test.runner.AndroidJUnit4; @@ -751,4 +752,72 @@ public class APITestPipeline { /* 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(); + } + } } diff --git a/api/android/api/src/main/jni/Android-nnstreamer.mk b/api/android/api/src/main/jni/Android-nnstreamer.mk index 30e0fa2..d2ee946 100644 --- a/api/android/api/src/main/jni/Android-nnstreamer.mk +++ b/api/android/api/src/main/jni/Android-nnstreamer.mk @@ -17,6 +17,8 @@ NNSTREAMER_SRC_FILES := \ $(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) \ diff --git a/api/android/api/src/main/jni/Android.mk b/api/android/api/src/main/jni/Android.mk index 5bbb2d9..5554b34 100644 --- a/api/android/api/src/main/jni/Android.mk +++ b/api/android/api/src/main/jni/Android.mk @@ -52,7 +52,7 @@ LOCAL_CFLAGS += -O2 -DVERSION=\"$(NNSTREAMER_VERSION)\" 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 diff --git a/api/android/api/src/main/jni/nnstreamer-native-api.c b/api/android/api/src/main/jni/nnstreamer-native-api.c index ffce950..5688d78 100644 --- a/api/android/api/src/main/jni/nnstreamer-native-api.c +++ b/api/android/api/src/main/jni/nnstreamer-native-api.c @@ -25,6 +25,10 @@ /* 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); @@ -36,6 +40,11 @@ extern void init_pose (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 * @@ -562,32 +571,49 @@ nns_get_nnfw_type (jint fw_type, ml_nnfw_type_e * nnfw) 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; } /** diff --git a/api/android/build-android-lib.sh b/api/android/build-android-lib.sh index 2129500..9c92edc 100644 --- a/api/android/build-android-lib.sh +++ b/api/android/build-android-lib.sh @@ -227,7 +227,10 @@ if [[ -e $nnstreamer_android_api_lib ]]; then 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 diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_cpp.cc b/ext/nnstreamer/tensor_filter/tensor_filter_cpp.cc index f49f8cc..e10f810 100644 --- a/ext/nnstreamer/tensor_filter/tensor_filter_cpp.cc +++ b/ext/nnstreamer/tensor_filter/tensor_filter_cpp.cc @@ -38,9 +38,6 @@ #include "tensor_filter_cpp.h" -void init_filter_cpp (void) __attribute__ ((constructor)); -void fini_filter_cpp (void) __attribute__ ((destructor)); - std::unordered_map tensor_filter_cpp::filters; static gchar filter_subplugin_cpp[] = "cpp"; @@ -236,6 +233,10 @@ void tensor_filter_cpp::close (const GstTensorFilterProperties *prop, void **pri 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) @@ -249,3 +250,4 @@ fini_filter_cpp (void) { nnstreamer_filter_exit (NNS_support_cpp.name); } +G_END_DECLS diff --git a/gst/nnstreamer/tensor_filter/tensor_filter_custom.c b/gst/nnstreamer/tensor_filter/tensor_filter_custom.c index 9e868a9..98afa5b 100644 --- a/gst/nnstreamer/tensor_filter/tensor_filter_custom.c +++ b/gst/nnstreamer/tensor_filter/tensor_filter_custom.c @@ -34,8 +34,8 @@ #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; @@ -261,14 +261,14 @@ 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); diff --git a/gst/nnstreamer/tensor_filter/tensor_filter_custom_easy.c b/gst/nnstreamer/tensor_filter/tensor_filter_custom_easy.c index ac853a3..e99676b 100644 --- a/gst/nnstreamer/tensor_filter/tensor_filter_custom_easy.c +++ b/gst/nnstreamer/tensor_filter/tensor_filter_custom_easy.c @@ -28,8 +28,8 @@ #include #include -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 @@ -180,15 +180,15 @@ static GstTensorFilterFramework NNS_support_custom_easy = { }; /** @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); } diff --git a/jni/nnstreamer.mk b/jni/nnstreamer.mk index bcbbc48..060e8d6 100644 --- a/jni/nnstreamer.mk +++ b/jni/nnstreamer.mk @@ -34,6 +34,7 @@ NNSTREAMER_PLUGINS_SRCS := \ $(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 \ @@ -55,6 +56,15 @@ NNSTREAMER_CAPI_SRCS := \ $(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