[API] Remove API directory
authorYongjoo Ahn <yongjoo1.ahn@samsung.com>
Thu, 11 Mar 2021 05:28:14 +0000 (14:28 +0900)
committerjaeyun-jung <39614140+jaeyun-jung@users.noreply.github.com>
Mon, 22 Mar 2021 06:00:40 +0000 (15:00 +0900)
- Finish migration of API related code to ML API repo (github.com/nnstreamer/api)

Signed-off-by: Yongjoo Ahn <yongjoo1.ahn@samsung.com>
53 files changed:
api/android/api/build.gradle [deleted file]
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCommon.java [deleted file]
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCustomFilter.java [deleted file]
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestPipeline.java [deleted file]
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestSingleShot.java [deleted file]
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestTensorsData.java [deleted file]
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestTensorsInfo.java [deleted file]
api/android/api/src/main/AndroidManifest.xml [deleted file]
api/android/api/src/main/java/org/nnsuite/nnstreamer/CustomFilter.java [deleted file]
api/android/api/src/main/java/org/nnsuite/nnstreamer/NNStreamer.java [deleted file]
api/android/api/src/main/java/org/nnsuite/nnstreamer/Pipeline.java [deleted file]
api/android/api/src/main/java/org/nnsuite/nnstreamer/SingleShot.java [deleted file]
api/android/api/src/main/java/org/nnsuite/nnstreamer/TensorsData.java [deleted file]
api/android/api/src/main/java/org/nnsuite/nnstreamer/TensorsInfo.java [deleted file]
api/android/api/src/main/jni/Android-dec-flatbuf.mk [deleted file]
api/android/api/src/main/jni/Android-gst-plugins.mk [deleted file]
api/android/api/src/main/jni/Android-nnfw-prebuilt.mk [deleted file]
api/android/api/src/main/jni/Android-nnfw.mk [deleted file]
api/android/api/src/main/jni/Android-nnstreamer-prebuilt.mk [deleted file]
api/android/api/src/main/jni/Android-nnstreamer.mk [deleted file]
api/android/api/src/main/jni/Android-pytorch.mk [deleted file]
api/android/api/src/main/jni/Android-snap-prebuilt.mk [deleted file]
api/android/api/src/main/jni/Android-snap.mk [deleted file]
api/android/api/src/main/jni/Android-snpe-prebuilt.mk [deleted file]
api/android/api/src/main/jni/Android-snpe.mk [deleted file]
api/android/api/src/main/jni/Android-tensorflow-lite.mk [deleted file]
api/android/api/src/main/jni/Android.mk [deleted file]
api/android/api/src/main/jni/Application.mk [deleted file]
api/android/api/src/main/jni/nnstreamer-native-api.c [deleted file]
api/android/api/src/main/jni/nnstreamer-native-customfilter.c [deleted file]
api/android/api/src/main/jni/nnstreamer-native-pipeline.c [deleted file]
api/android/api/src/main/jni/nnstreamer-native-singleshot.c [deleted file]
api/android/api/src/main/jni/nnstreamer-native.h [deleted file]
api/android/build-android-lib.sh [deleted file]
api/android/build.gradle [deleted file]
api/android/settings.gradle [deleted file]
api/capi/capi-ml-common.pc.in [deleted file]
api/capi/capi-nnstreamer.pc.in [deleted file]
api/capi/doc/images/capi_nnstreamer_pipeline_state.jpg [deleted file]
api/capi/doc/nnstreamer_doc.h [deleted file]
api/capi/include/ml-api-common.h [deleted file]
api/capi/include/nnstreamer-capi-private.h [deleted file]
api/capi/include/nnstreamer-single.h [deleted file]
api/capi/include/nnstreamer-tizen-internal.h [deleted file]
api/capi/include/nnstreamer.h [deleted file]
api/capi/include/platform/tizen_error.h [deleted file]
api/capi/meson.build [deleted file]
api/capi/src/README.md [deleted file]
api/capi/src/nnstreamer-capi-pipeline.c [deleted file]
api/capi/src/nnstreamer-capi-single.c [deleted file]
api/capi/src/nnstreamer-capi-tizen-feature-check.c [deleted file]
api/capi/src/nnstreamer-capi-tizen-privilege-check.c [deleted file]
api/capi/src/nnstreamer-capi-util.c [deleted file]

diff --git a/api/android/api/build.gradle b/api/android/api/build.gradle
deleted file mode 100644 (file)
index d9f7211..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-apply plugin: 'com.android.library'
-// add plugin (bintray)
-
-android {
-    compileSdkVersion 28
-    buildToolsVersion '28.0.3'
-    defaultConfig {
-        minSdkVersion 28
-        targetSdkVersion 28
-        versionCode 1
-        versionName "1.0"
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-        externalNativeBuild {
-            ndkBuild {
-                def gstRoot
-
-                if (project.hasProperty('gstAndroidRoot'))
-                    gstRoot = project.gstAndroidRoot
-                else
-                    gstRoot = System.env.GSTREAMER_ROOT_ANDROID
-
-                if (gstRoot == null)
-                    throw new GradleException('GSTREAMER_ROOT_ANDROID must be set, or "gstAndroidRoot" must be defined in your gradle.properties in the top level directory of the unpacked universal GStreamer Android binaries')
-
-                def nnsRoot
-
-                if (project.hasProperty('nnstreamerRoot'))
-                    nnsRoot = project.nnstreamerRoot
-                else
-                    nnsRoot = System.env.NNSTREAMER_ROOT
-
-                if (nnsRoot == null)
-                    throw new GradleException('NNSTREAMER_ROOT must be set, or "nnstreamerRoot" must be defined in your gradle.properties')
-
-                arguments "NDK_APPLICATION_MK=src/main/jni/Application.mk",
-                          "GSTREAMER_JAVA_SRC_DIR=src/main/java",
-                          "GSTREAMER_ROOT_ANDROID=$gstRoot",
-                          "GSTREAMER_ASSETS_DIR=src/main/assets",
-                          "NNSTREAMER_ROOT=$nnsRoot"
-
-                targets "nnstreamer-native"
-
-                abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
-            }
-        }
-    }
-    buildTypes {
-        debug {
-            testCoverageEnabled true
-        }
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
-        }
-    }
-    externalNativeBuild {
-        ndkBuild {
-            path 'src/main/jni/Android.mk'
-        }
-    }
-    productFlavors {
-    }
-    sourceSets {
-        main {
-            if (project.hasProperty('SNPE_EXT_LIBRARY_PATH')) {
-                jniLibs.srcDirs += project.properties['SNPE_EXT_LIBRARY_PATH']
-                println 'Set jniLibs.srcDirs includes libraries for SNPE'
-            }
-
-            if (project.hasProperty('NNFW_EXT_LIBRARY_PATH')) {
-                jniLibs.srcDirs += project.properties['NNFW_EXT_LIBRARY_PATH']
-                println 'Set jniLibs.srcDirs includes libraries for NNFW'
-            }
-        }
-    }
-    packagingOptions {
-        // To do not show build warning messages
-        doNotStrip "*/arm64-v8a/*_skel.so"
-    }
-}
-
-dependencies {
-    implementation fileTree(include: ['*.jar'], dir: 'libs')
-    implementation 'com.android.support:appcompat-v7:28.0.0'
-    testImplementation 'junit:junit:4.12'
-    androidTestImplementation 'com.android.support.test:rules:1.0.2'
-    androidTestImplementation 'com.android.support.test:runner:1.0.2'
-    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
-}
diff --git a/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCommon.java b/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCommon.java
deleted file mode 100644 (file)
index d526d0c..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-package org.nnsuite.nnstreamer;
-
-import android.Manifest;
-import android.content.Context;
-import android.os.Environment;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.rule.GrantPermissionRule;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.file.Files;
-
-import static org.junit.Assert.*;
-
-/**
- * Common definition to test NNStreamer API.
- *
- * Instrumented test, which will execute on an Android device.
- *
- * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
- */
-@RunWith(AndroidJUnit4.class)
-public class APITestCommon {
-    private static boolean mInitialized = false;
-
-    /**
-     * Initializes NNStreamer API library.
-     */
-    public static void initNNStreamer() {
-        if (!mInitialized) {
-            try {
-                Context context = InstrumentationRegistry.getTargetContext();
-                mInitialized = NNStreamer.initialize(context);
-            } catch (Exception e) {
-                fail();
-            }
-        }
-    }
-
-    /**
-     * Gets the context for the test application.
-     */
-    public static Context getContext() {
-        return InstrumentationRegistry.getTargetContext();
-    }
-
-    /**
-     * Grants required runtime permissions.
-     */
-    public static GrantPermissionRule grantPermissions() {
-        return GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE);
-    }
-
-    /**
-     * Gets the File object of tensorflow-lite model.
-     * Note that, to invoke model in the storage, the permission READ_EXTERNAL_STORAGE is required.
-     */
-    public static File getTFLiteImgModel() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-        File model = new File(root + "/nnstreamer/test/imgclf/mobilenet_v1_1.0_224_quant.tflite");
-        File meta = new File(root + "/nnstreamer/test/imgclf/metadata/MANIFEST");
-
-        if (!model.exists() || !meta.exists()) {
-            fail();
-        }
-
-        return model;
-    }
-
-    /**
-     * Reads raw image file (orange) and returns TensorsData instance.
-     */
-    public static TensorsData readRawImageData() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-        File raw = new File(root + "/nnstreamer/test/orange.raw");
-
-        if (!raw.exists()) {
-            fail();
-        }
-
-        TensorsInfo info = new TensorsInfo();
-        info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{3,224,224,1});
-
-        int size = info.getTensorSize(0);
-        TensorsData data = TensorsData.allocate(info);
-
-        try {
-            byte[] content = Files.readAllBytes(raw.toPath());
-            if (content.length != size) {
-                fail();
-            }
-
-            ByteBuffer buffer = TensorsData.allocateByteBuffer(size);
-            buffer.put(content);
-
-            data.setTensorData(0, buffer);
-        } catch (Exception e) {
-            fail();
-        }
-
-        return data;
-    }
-
-    /**
-     * Gets the label index with max score, for tensorflow-lite image classification.
-     */
-    public static int getMaxScore(ByteBuffer buffer) {
-        int index = -1;
-        int maxScore = 0;
-
-        if (isValidBuffer(buffer, 1001)) {
-            for (int i = 0; i < 1001; i++) {
-                /* convert unsigned byte */
-                int score = (buffer.get(i) & 0xFF);
-
-                if (score > maxScore) {
-                    maxScore = score;
-                    index = i;
-                }
-            }
-        }
-
-        return index;
-    }
-
-    /**
-     * Reads raw float image file (orange) and returns TensorsData instance.
-     */
-    public static TensorsData readRawImageDataPytorch() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-        File raw = new File(root + "/nnstreamer/pytorch_data/orange_float.raw");
-
-        if (!raw.exists()) {
-            fail();
-        }
-
-        TensorsInfo info = new TensorsInfo();
-        info.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{224, 224, 3, 1});
-
-        int size = info.getTensorSize(0);
-        TensorsData data = TensorsData.allocate(info);
-
-        try {
-            byte[] content = Files.readAllBytes(raw.toPath());
-            if (content.length != size) {
-                fail();
-            }
-
-            ByteBuffer buffer = TensorsData.allocateByteBuffer(size);
-            buffer.put(content);
-
-            data.setTensorData(0, buffer);
-        } catch (Exception e) {
-            fail();
-        }
-
-        return data;
-    }
-
-    /**
-     * Gets the label index with max score for float buffer with given length.
-     */
-    public static int getMaxScoreFloatBuffer(ByteBuffer buffer, int length) {
-        int index = -1;
-        float maxScore = -Float.MAX_VALUE;
-
-        if (isValidBuffer(buffer, 4 * length)) {
-            for (int i = 0; i < length; i++) {
-                /* convert to float */
-                float score = buffer.getFloat(i * 4);
-
-                if (score > maxScore) {
-                    maxScore = score;
-                    index = i;
-                }
-            }
-        }
-
-        return index;
-    }
-
-    /**
-     * Reads raw float image file (plastic_cup) and returns TensorsData instance.
-     */
-    public static TensorsData readRawImageDataSNPE() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-        File raw = new File(root + "/nnstreamer/snpe_data/plastic_cup.raw");
-
-        if (!raw.exists()) {
-            fail();
-        }
-
-        TensorsInfo info = new TensorsInfo();
-        info.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{3, 299, 299, 1});
-
-        int size = info.getTensorSize(0);
-        TensorsData data = TensorsData.allocate(info);
-
-        try {
-            byte[] content = Files.readAllBytes(raw.toPath());
-            if (content.length != size) {
-                fail();
-            }
-
-            ByteBuffer buffer = TensorsData.allocateByteBuffer(size);
-            buffer.put(content);
-
-            data.setTensorData(0, buffer);
-        } catch (Exception e) {
-            fail();
-        }
-
-        return data;
-    }
-
-    /**
-     * Gets the path string of tensorflow-lite add.tflite model.
-     */
-    public static String getTFLiteAddModelPath() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-        return root + "/nnstreamer/test/add";
-    }
-
-    /**
-     * Gets the File object of tensorflow-lite add.tflite model.
-     * Note that, to invoke model in the storage, the permission READ_EXTERNAL_STORAGE is required.
-     */
-    public static File getTFLiteAddModel() {
-        String path = getTFLiteAddModelPath();
-        File model = new File(path + "/add.tflite");
-        File meta = new File(path + "/metadata/MANIFEST");
-
-        if (!model.exists() || !meta.exists()) {
-            fail();
-        }
-
-        return model;
-    }
-
-    public enum SNAPComputingUnit {
-        CPU("ComputingUnit:CPU"),
-        GPU("ComputingUnit:GPU,GpuCacheSource:/sdcard/nnstreamer/"),
-        DSP("ComputingUnit:DSP"),
-        NPU("ComputingUnit:NPU");
-
-        private String computing_unit_option;
-
-        SNAPComputingUnit(String computing_unit_option) {
-            this.computing_unit_option = computing_unit_option;
-        }
-
-        public String getOptionString() {
-            return computing_unit_option;
-        }
-    }
-
-    /**
-     * Gets the File objects of Caffe model for SNAP.
-     * Note that, to invoke model in the storage, the permission READ_EXTERNAL_STORAGE is required.
-     */
-    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(SNAPComputingUnit CUnit) {
-        String option = "ModelFWType:CAFFE,ExecutionDataType:FLOAT32,InputFormat:NHWC,OutputFormat:NCHW,";
-        option = option + CUnit.getOptionString();
-
-        return option;
-    }
-
-    /**
-     * Gets the option string to run Tensorflow model for SNAP.
-     *
-     * CPU: "custom=ModelFWType:CAFFE,ExecutionDataType:FLOAT32,ComputingUnit:CPU"
-     * GPU: Not supported for Tensorflow model
-     * DSP: "custom=ModelFWType:CAFFE,ExecutionDataType:FLOAT32,ComputingUnit:DSP"
-     * NPU: "custom=ModelFWType:CAFFE,ExecutionDataType:FLOAT32,ComputingUnit:NPU"
-     */
-    public static String getSNAPTensorflowOption(SNAPComputingUnit CUnit) {
-        String option = "ModelFWType:TENSORFLOW,ExecutionDataType:FLOAT32,InputFormat:NHWC,OutputFormat:NHWC,";
-        option = option + CUnit.getOptionString();
-        return option;
-    }
-
-    /**
-     * Gets the File objects of Tensorflow model for SNAP.
-     * Note that, to invoke model in the storage, the permission READ_EXTERNAL_STORAGE is required.
-     */
-    public static File[] getSNAPTensorflowModel(SNAPComputingUnit CUnit) {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-        String model_path = "/nnstreamer/snap_data/model/";
-
-        switch (CUnit) {
-            case CPU:
-                model_path = model_path + "yolo_new.pb";
-                break;
-            case DSP:
-                model_path = model_path + "yolo_new_tf_quantized.dlc";
-                break;
-            case NPU:
-                model_path = model_path + "yolo_new_tf_quantized_hta.dlc";
-                break;
-            case GPU:
-            default:
-                fail();
-        }
-
-        File model = new File(root + model_path);
-        if (!model.exists()) {
-            fail();
-        }
-
-        return new File[]{model};
-    }
-
-    public static File getSNPEModel() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-
-        File model = new File(root + "/nnstreamer/snpe_data/inception_v3_quantized.dlc");
-
-        if (!model.exists()) {
-            fail();
-        }
-
-        return model;
-    }
-
-    /**
-     * Get the File object of SNPE model for testing multiple output.
-     * The model is converted to dlc format with SNPE SDK and it's from
-     * https://github.com/nnsuite/testcases/tree/master/DeepLearningModels/tensorflow/ssdlite_mobilenet_v2
-     */
-    public static File getMultiOutputSNPEModel() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-
-        File model = new File(root + "/nnstreamer/snpe_data/ssdlite_mobilenet_v2.dlc");
-
-        if (!model.exists()) {
-            fail();
-        }
-
-        return model;
-    }
-
-    public static File getPytorchModel() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-
-        File model = new File(root + "/nnstreamer/pytorch_data/mobilenetv2-quant_core-nnapi.pt");
-
-        if (!model.exists()) {
-            fail();
-        }
-
-        return model;
-    }
-
-    /**
-     * Verifies the byte buffer is direct buffer with native order.
-     *
-     * @param buffer   The byte buffer
-     * @param expected The expected capacity
-     *
-     * @return True if the byte buffer is valid.
-     */
-    public static boolean isValidBuffer(ByteBuffer buffer, int expected) {
-        if (buffer != null && buffer.isDirect() && buffer.order() == ByteOrder.nativeOrder()) {
-            int capacity = buffer.capacity();
-
-            return (capacity == expected);
-        }
-
-        return false;
-    }
-
-    @Before
-    public void setUp() {
-        initNNStreamer();
-    }
-
-    @Test
-    public void useAppContext() {
-        Context context = InstrumentationRegistry.getTargetContext();
-
-        assertEquals("org.nnsuite.nnstreamer.test", context.getPackageName());
-    }
-
-    @Test
-    public void testInitWithInvalidCtx_n() {
-        try {
-            NNStreamer.initialize(null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void enumTensorType() {
-        assertEquals(NNStreamer.TensorType.INT32, NNStreamer.TensorType.valueOf("INT32"));
-        assertEquals(NNStreamer.TensorType.UINT32, NNStreamer.TensorType.valueOf("UINT32"));
-        assertEquals(NNStreamer.TensorType.INT16, NNStreamer.TensorType.valueOf("INT16"));
-        assertEquals(NNStreamer.TensorType.UINT16, NNStreamer.TensorType.valueOf("UINT16"));
-        assertEquals(NNStreamer.TensorType.INT8, NNStreamer.TensorType.valueOf("INT8"));
-        assertEquals(NNStreamer.TensorType.UINT8, NNStreamer.TensorType.valueOf("UINT8"));
-        assertEquals(NNStreamer.TensorType.FLOAT64, NNStreamer.TensorType.valueOf("FLOAT64"));
-        assertEquals(NNStreamer.TensorType.FLOAT32, NNStreamer.TensorType.valueOf("FLOAT32"));
-        assertEquals(NNStreamer.TensorType.INT64, NNStreamer.TensorType.valueOf("INT64"));
-        assertEquals(NNStreamer.TensorType.UINT64, NNStreamer.TensorType.valueOf("UINT64"));
-        assertEquals(NNStreamer.TensorType.UNKNOWN, NNStreamer.TensorType.valueOf("UNKNOWN"));
-    }
-
-    @Test
-    public void enumNNFWType() {
-        assertEquals(NNStreamer.NNFWType.TENSORFLOW_LITE, NNStreamer.NNFWType.valueOf("TENSORFLOW_LITE"));
-        assertEquals(NNStreamer.NNFWType.SNAP, NNStreamer.NNFWType.valueOf("SNAP"));
-        assertEquals(NNStreamer.NNFWType.NNFW, NNStreamer.NNFWType.valueOf("NNFW"));
-        assertEquals(NNStreamer.NNFWType.SNPE, NNStreamer.NNFWType.valueOf("SNPE"));
-        assertEquals(NNStreamer.NNFWType.PYTORCH, NNStreamer.NNFWType.valueOf("PYTORCH"));
-        assertEquals(NNStreamer.NNFWType.UNKNOWN, NNStreamer.NNFWType.valueOf("UNKNOWN"));
-    }
-}
diff --git a/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCustomFilter.java b/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCustomFilter.java
deleted file mode 100644 (file)
index a8130b9..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-package org.nnsuite.nnstreamer;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.nio.ByteBuffer;
-
-import static org.junit.Assert.*;
-
-/**
- * Testcases for CustomFilter.
- */
-@RunWith(AndroidJUnit4.class)
-public class APITestCustomFilter {
-    private int mReceived = 0;
-    private boolean mInvalidState = false;
-    private boolean mRegistered = false;
-    private CustomFilter mCustomPassthrough;
-    private CustomFilter mCustomConvert;
-    private CustomFilter mCustomAdd;
-
-    private Pipeline.NewDataCallback mSinkCb = 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;
-                return;
-            }
-
-            ByteBuffer output = data.getTensorData(0);
-
-            for (int i = 0; i < 10; i++) {
-                float expected = i + 1.5f;
-
-                if (expected != output.getFloat(i * 4)) {
-                    mInvalidState = true;
-                }
-            }
-
-            mReceived++;
-        }
-    };
-
-    private void registerCustomFilters() {
-        try {
-            TensorsInfo inputInfo = new TensorsInfo();
-            inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
-
-            TensorsInfo outputInfo = inputInfo.clone();
-
-            /* register custom-filter (passthrough) */
-            mCustomPassthrough = CustomFilter.create("custom-passthrough",
-                    inputInfo, outputInfo, new CustomFilter.Callback() {
-                @Override
-                public TensorsData invoke(TensorsData in) {
-                    return in;
-                }
-            });
-
-            /* register custom-filter (convert data type to float) */
-            outputInfo.setTensorType(0, NNStreamer.TensorType.FLOAT32);
-            mCustomConvert = CustomFilter.create("custom-convert",
-                    inputInfo, outputInfo, new CustomFilter.Callback() {
-                @Override
-                public TensorsData invoke(TensorsData in) {
-                    TensorsInfo info = in.getTensorsInfo();
-                    ByteBuffer input = in.getTensorData(0);
-
-                    info.setTensorType(0, NNStreamer.TensorType.FLOAT32);
-
-                    TensorsData out = info.allocate();
-                    ByteBuffer output = out.getTensorData(0);
-
-                    for (int i = 0; i < 10; i++) {
-                        float value = (float) input.getInt(i * 4);
-                        output.putFloat(i * 4, value);
-                    }
-
-                    out.setTensorData(0, output);
-                    return out;
-                }
-            });
-
-            /* register custom-filter (add constant) */
-            inputInfo.setTensorType(0, NNStreamer.TensorType.FLOAT32);
-            mCustomAdd = CustomFilter.create("custom-add",
-                    inputInfo, outputInfo, new CustomFilter.Callback() {
-                @Override
-                public TensorsData invoke(TensorsData in) {
-                    TensorsInfo info = in.getTensorsInfo();
-                    ByteBuffer input = in.getTensorData(0);
-
-                    TensorsData out = info.allocate();
-                    ByteBuffer output = out.getTensorData(0);
-
-                    for (int i = 0; i < 10; i++) {
-                        float value = input.getFloat(i * 4);
-
-                        /* add constant */
-                        value += 1.5f;
-                        output.putFloat(i * 4, value);
-                    }
-
-                    out.setTensorData(0, output);
-                    return out;
-                }
-            });
-
-            mRegistered = true;
-        } catch (Exception e) {
-            /* failed to register custom-filters */
-            fail();
-        }
-    }
-
-    @Before
-    public void setUp() {
-        APITestCommon.initNNStreamer();
-
-        mReceived = 0;
-        mInvalidState = false;
-
-        if (!mRegistered) {
-            registerCustomFilters();
-        }
-    }
-
-    @After
-    public void tearDown() {
-        if (mRegistered) {
-            mCustomPassthrough.close();
-            mCustomConvert.close();
-            mCustomAdd.close();
-        }
-    }
-
-    @Test
-    public void testGetName() {
-        try {
-            assertEquals("custom-passthrough", mCustomPassthrough.getName());
-            assertEquals("custom-convert", mCustomConvert.getName());
-            assertEquals("custom-add", mCustomAdd.getName());
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testCustomFilters() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)10:1:1:1,type=(string)int32,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=custom-easy model=" + mCustomPassthrough.getName() + " ! " +
-                "tensor_filter framework=custom-easy model=" + mCustomConvert.getName() + " ! " +
-                "tensor_filter framework=custom-easy model=" + mCustomAdd.getName() + " ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
-
-            /* register sink callback */
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer repeatedly */
-            for (int i = 0; i < 2048; i++) {
-                TensorsData in = TensorsData.allocate(info);
-                ByteBuffer input = in.getTensorData(0);
-
-                for (int j = 0; j < 10; j++) {
-                    input.putInt(j * 4, j);
-                }
-
-                in.setTensorData(0, input);
-
-                pipe.inputData("srcx", in);
-                Thread.sleep(20);
-            }
-
-            /* sleep 300 to pass all input buffers to sink */
-            Thread.sleep(300);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertEquals(2048, mReceived);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testDropBuffer() {
-        TensorsInfo inputInfo = new TensorsInfo();
-        inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10,1,1,1});
-
-        TensorsInfo outputInfo = inputInfo.clone();
-
-        CustomFilter customDrop = CustomFilter.create("custom-drop",
-                inputInfo, outputInfo, new CustomFilter.Callback() {
-            int received = 0;
-
-            @Override
-            public TensorsData invoke(TensorsData in) {
-                received++;
-
-                if (received <= 5) {
-                    return in;
-                }
-
-                /* return null to drop the incoming buffer */
-                return null;
-            }
-        });
-
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)10:1:1:1,type=(string)int32,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=custom-easy model=" + customDrop.getName() + " ! " +
-                "tensor_filter framework=custom-easy model=" + mCustomPassthrough.getName() + " ! " +
-                "tensor_filter framework=custom-easy model=" + mCustomConvert.getName() + " ! " +
-                "tensor_filter framework=custom-easy model=" + mCustomAdd.getName() + " ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10,1,1,1});
-
-            /* register sink callback */
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer repeatedly */
-            for (int i = 0; i < 24; i++) {
-                TensorsData in = TensorsData.allocate(info);
-                ByteBuffer input = in.getTensorData(0);
-
-                for (int j = 0; j < 10; j++) {
-                    input.putInt(j * 4, j);
-                }
-
-                in.setTensorData(0, input);
-
-                pipe.inputData("srcx", in);
-                Thread.sleep(20);
-            }
-
-            /* sleep 300 to pass input buffers to sink */
-            Thread.sleep(300);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertEquals(5, mReceived);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testRegisterNullName_n() {
-        TensorsInfo inputInfo = new TensorsInfo();
-        inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
-
-        TensorsInfo outputInfo = inputInfo.clone();
-
-        try {
-            CustomFilter.create(null, inputInfo, outputInfo,
-                    new CustomFilter.Callback() {
-                @Override
-                public TensorsData invoke(TensorsData in) {
-                    return in;
-                }
-            });
-
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRegisterNullInputInfo_n() {
-        TensorsInfo outputInfo = new TensorsInfo();
-        outputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
-
-        try {
-            CustomFilter.create("custom-invalid-info", null, outputInfo,
-                    new CustomFilter.Callback() {
-                @Override
-                public TensorsData invoke(TensorsData in) {
-                    return in;
-                }
-            });
-
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRegisterNullOutputInfo_n() {
-        TensorsInfo inputInfo = new TensorsInfo();
-        inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
-
-        try {
-            CustomFilter.create("custom-invalid-info", inputInfo, null,
-                    new CustomFilter.Callback() {
-                @Override
-                public TensorsData invoke(TensorsData in) {
-                    return in;
-                }
-            });
-
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRegisterNullCallback_n() {
-        TensorsInfo inputInfo = new TensorsInfo();
-        inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
-
-        TensorsInfo outputInfo = inputInfo.clone();
-
-        try {
-            CustomFilter.create("custom-invalid-cb", inputInfo, outputInfo, null);
-
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRegisterDuplicatedName_n() {
-        TensorsInfo inputInfo = new TensorsInfo();
-        inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
-
-        TensorsInfo outputInfo = inputInfo.clone();
-
-        try {
-            CustomFilter.create(mCustomPassthrough.getName(), inputInfo, outputInfo,
-                    new CustomFilter.Callback() {
-                @Override
-                public TensorsData invoke(TensorsData in) {
-                    return in;
-                }
-            });
-
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRegisterPreservedName_n() {
-        TensorsInfo inputInfo = new TensorsInfo();
-        inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
-
-        TensorsInfo outputInfo = inputInfo.clone();
-
-        try {
-            CustomFilter.create("auto", inputInfo, outputInfo,
-                    new CustomFilter.Callback() {
-                @Override
-                public TensorsData invoke(TensorsData in) {
-                    return in;
-                }
-            });
-
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-}
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
deleted file mode 100644 (file)
index b6b2220..0000000
+++ /dev/null
@@ -1,2074 +0,0 @@
-package org.nnsuite.nnstreamer;
-
-import android.os.Environment;
-import android.support.test.rule.GrantPermissionRule;
-import android.support.test.runner.AndroidJUnit4;
-import android.view.SurfaceView;
-
-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 java.util.Arrays;
-
-import static org.junit.Assert.*;
-
-/**
- * Testcases for Pipeline.
- */
-@RunWith(AndroidJUnit4.class)
-public class APITestPipeline {
-    private int mReceived = 0;
-    private boolean mInvalidState = false;
-    private Pipeline.State mPipelineState = Pipeline.State.NULL;
-
-    private Pipeline.NewDataCallback mSinkCb = new Pipeline.NewDataCallback() {
-        @Override
-        public void onNewDataReceived(TensorsData data) {
-            if (data == null ||
-                data.getTensorsCount() != 1 ||
-                data.getTensorData(0).capacity() != 200) {
-                mInvalidState = true;
-                return;
-            }
-
-            TensorsInfo info = data.getTensorsInfo();
-
-            /* validate received data (unit8 2:10:10:1) */
-            if (info == null ||
-                info.getTensorsCount() != 1 ||
-                info.getTensorName(0) != null ||
-                info.getTensorType(0) != NNStreamer.TensorType.UINT8 ||
-                !Arrays.equals(info.getTensorDimension(0), new int[]{2,10,10,1})) {
-                /* received data is invalid */
-                mInvalidState = true;
-            }
-
-            mReceived++;
-        }
-    };
-
-    @Rule
-    public GrantPermissionRule mPermissionRule = APITestCommon.grantPermissions();
-
-    @Before
-    public void setUp() {
-        APITestCommon.initNNStreamer();
-
-        mReceived = 0;
-        mInvalidState = false;
-        mPipelineState = Pipeline.State.NULL;
-    }
-
-    @Test
-    public void enumPipelineState() {
-        assertEquals(Pipeline.State.UNKNOWN, Pipeline.State.valueOf("UNKNOWN"));
-        assertEquals(Pipeline.State.NULL, Pipeline.State.valueOf("NULL"));
-        assertEquals(Pipeline.State.READY, Pipeline.State.valueOf("READY"));
-        assertEquals(Pipeline.State.PAUSED, Pipeline.State.valueOf("PAUSED"));
-        assertEquals(Pipeline.State.PLAYING, Pipeline.State.valueOf("PLAYING"));
-    }
-
-    @Test
-    public void testAvailableElement() {
-        try {
-            assertTrue(Pipeline.isElementAvailable("tensor_converter"));
-            assertTrue(Pipeline.isElementAvailable("tensor_filter"));
-            assertTrue(Pipeline.isElementAvailable("tensor_transform"));
-            assertTrue(Pipeline.isElementAvailable("tensor_sink"));
-            assertTrue(Pipeline.isElementAvailable("join"));
-            assertTrue(Pipeline.isElementAvailable("amcsrc"));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testAvailableElementNullName_n() {
-        try {
-            Pipeline.isElementAvailable(null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testAvailableElementEmptyName_n() {
-        try {
-            Pipeline.isElementAvailable("");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testAvailableElementInvalidName_n() {
-        try {
-            assertFalse(Pipeline.isElementAvailable("invalid-element"));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testConstructInvalidElement_n() {
-        String desc = "videotestsrc ! videoconvert ! video/x-raw,format=RGB ! " +
-                "invalidelement ! tensor_converter ! tensor_sink";
-
-        try {
-            new Pipeline(desc);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testConstructNullDescription_n() {
-        try {
-            new Pipeline(null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testConstructEmptyDescription_n() {
-        try {
-            new Pipeline("");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testConstructNullStateCb() {
-        String desc = "videotestsrc ! videoconvert ! video/x-raw,format=RGB ! " +
-                "tensor_converter ! tensor_sink";
-
-        try (Pipeline pipe = new Pipeline(desc, null)) {
-            Thread.sleep(100);
-            assertEquals(Pipeline.State.PAUSED, pipe.getState());
-            Thread.sleep(100);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testConstructWithStateCb() {
-        String desc = "videotestsrc ! videoconvert ! video/x-raw,format=RGB ! " +
-                "tensor_converter ! tensor_sink";
-
-        /* pipeline state callback */
-        Pipeline.StateChangeCallback stateCb = new Pipeline.StateChangeCallback() {
-            @Override
-            public void onStateChanged(Pipeline.State state) {
-                mPipelineState = state;
-            }
-        };
-
-        try (Pipeline pipe = new Pipeline(desc, stateCb)) {
-            Thread.sleep(100);
-            assertEquals(Pipeline.State.PAUSED, mPipelineState);
-
-            /* start pipeline */
-            pipe.start();
-            Thread.sleep(300);
-
-            assertEquals(Pipeline.State.PLAYING, mPipelineState);
-
-            /* stop pipeline */
-            pipe.stop();
-            Thread.sleep(300);
-
-            assertEquals(Pipeline.State.PAUSED, mPipelineState);
-            Thread.sleep(100);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testGetState() {
-        String desc = "videotestsrc ! videoconvert ! video/x-raw,format=RGB ! " +
-                "tensor_converter ! tensor_sink";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-            Thread.sleep(300);
-
-            assertEquals(Pipeline.State.PLAYING, pipe.getState());
-
-            /* stop pipeline */
-            pipe.stop();
-            Thread.sleep(300);
-
-            assertEquals(Pipeline.State.PAUSED, pipe.getState());
-            Thread.sleep(100);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testRegisterNullDataCb_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.registerSinkCallback("sinkx", null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRegisterDataCbInvalidName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.registerSinkCallback("invalid_sink", mSinkCb);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRegisterDataCbNullName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.registerSinkCallback(null, mSinkCb);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRegisterDataCbEmptyName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.registerSinkCallback("", mSinkCb);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testUnregisterNullDataCb_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.unregisterSinkCallback("sinkx", null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testUnregisterDataCbNullName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.unregisterSinkCallback(null, mSinkCb);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testUnregisterDataCbEmptyName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.unregisterSinkCallback("", mSinkCb);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testUnregisteredDataCb_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.unregisterSinkCallback("sinkx", mSinkCb);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testUnregisterInvalidCb_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* register callback */
-            Pipeline.NewDataCallback cb1 = new Pipeline.NewDataCallback() {
-                @Override
-                public void onNewDataReceived(TensorsData data) {
-                    mReceived++;
-                }
-            };
-
-            pipe.registerSinkCallback("sinkx", cb1);
-
-            /* unregistered callback */
-            pipe.unregisterSinkCallback("sinkx", mSinkCb);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testRemoveDataCb() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            /* register sink callback */
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", info.allocate());
-                Thread.sleep(50);
-            }
-
-            /* pause pipeline and unregister sink callback */
-            Thread.sleep(100);
-            pipe.stop();
-
-            pipe.unregisterSinkCallback("sinkx", mSinkCb);
-            Thread.sleep(100);
-
-            /* start pipeline again */
-            pipe.start();
-
-            /* push input buffer again */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", info.allocate());
-                Thread.sleep(50);
-            }
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertEquals(10, mReceived);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testDuplicatedDataCb() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-
-            /* try to register same cb */
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", info.allocate());
-                Thread.sleep(50);
-            }
-
-            /* pause pipeline and unregister sink callback */
-            Thread.sleep(100);
-            pipe.stop();
-
-            pipe.unregisterSinkCallback("sinkx", mSinkCb);
-            Thread.sleep(100);
-
-            /* start pipeline again */
-            pipe.start();
-
-            /* push input buffer again */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", info.allocate());
-                Thread.sleep(50);
-            }
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertEquals(10, mReceived);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testMultipleDataCb() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            /* register three callbacks */
-            Pipeline.NewDataCallback cb1 = new Pipeline.NewDataCallback() {
-                @Override
-                public void onNewDataReceived(TensorsData data) {
-                    mReceived++;
-                }
-            };
-
-            Pipeline.NewDataCallback cb2 = new Pipeline.NewDataCallback() {
-                @Override
-                public void onNewDataReceived(TensorsData data) {
-                    mReceived++;
-                }
-            };
-
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-            pipe.registerSinkCallback("sinkx", cb1);
-            pipe.registerSinkCallback("sinkx", cb2);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", info.allocate());
-                Thread.sleep(50);
-            }
-
-            /* pause pipeline and unregister sink callback */
-            Thread.sleep(100);
-            pipe.stop();
-
-            pipe.unregisterSinkCallback("sinkx", mSinkCb);
-            pipe.unregisterSinkCallback("sinkx", cb1);
-            Thread.sleep(100);
-
-            /* start pipeline again */
-            pipe.start();
-
-            /* push input buffer again */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", info.allocate());
-                Thread.sleep(50);
-            }
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertEquals(40, mReceived);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testPushToTensorTransform() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)5:1:1:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_transform mode=arithmetic option=typecast:float32,add:0.5 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{5,1,1,1});
-
-            /* register callback */
-            Pipeline.NewDataCallback cb1 = new Pipeline.NewDataCallback() {
-                @Override
-                public void onNewDataReceived(TensorsData data) {
-                    if (data != null) {
-                        TensorsInfo info = data.getTensorsInfo();
-                        ByteBuffer buffer = data.getTensorData(0);
-
-                        /* validate received data (float32 5:1:1:1) */
-                        if (info == null ||
-                            info.getTensorsCount() != 1 ||
-                            info.getTensorType(0) != NNStreamer.TensorType.FLOAT32 ||
-                            !Arrays.equals(info.getTensorDimension(0), new int[]{5,1,1,1})) {
-                            /* received data is invalid */
-                            mInvalidState = true;
-                        }
-
-                        for (int i = 0; i < 5; i++) {
-                            float expected = i * 2 + mReceived + 0.5f;
-
-                            if (expected != buffer.getFloat(i * 4)) {
-                                mInvalidState = true;
-                            }
-                        }
-
-                        mReceived++;
-                    }
-                }
-            };
-
-            pipe.registerSinkCallback("sinkx", cb1);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            for (int i = 0; i < 10; i++) {
-                TensorsData in = info.allocate();
-                ByteBuffer buffer = in.getTensorData(0);
-
-                for (int j = 0; j < 5; j++) {
-                    buffer.put(j, (byte) (j * 2 + i));
-                }
-
-                in.setTensorData(0, buffer);
-
-                pipe.inputData("srcx", in);
-                Thread.sleep(50);
-            }
-
-            /* pause pipeline and unregister sink callback */
-            Thread.sleep(200);
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertEquals(10, mReceived);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testRunModel() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        File model = APITestCommon.getTFLiteImgModel();
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)3:224:224:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=tensorflow-lite model=" + model.getAbsolutePath() + " ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, 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, 1001)) {
-                            mInvalidState = true;
-                        }
-                    }
-
-                    mReceived++;
-                }
-            });
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            for (int i = 0; i < 15; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", TensorsData.allocate(info));
-                Thread.sleep(100);
-            }
-
-            /* sleep 500 to invoke */
-            Thread.sleep(500);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testClassificationResult() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        File model = APITestCommon.getTFLiteImgModel();
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)3:224:224:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=tensorflow-lite model=" + model.getAbsolutePath() + " ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, 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;
-                    }
-
-                    ByteBuffer buffer = data.getTensorData(0);
-                    int labelIndex = APITestCommon.getMaxScore(buffer);
-
-                    /* check label index (orange) */
-                    if (labelIndex != 951) {
-                        mInvalidState = true;
-                    }
-
-                    mReceived++;
-                }
-            });
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            TensorsData in = APITestCommon.readRawImageData();
-            pipe.inputData("srcx", in);
-
-            /* sleep 1000 to invoke */
-            Thread.sleep(1000);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testInputBuffer() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            /* register sink callback */
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer repeatedly */
-            for (int i = 0; i < 2048; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", TensorsData.allocate(info));
-                Thread.sleep(20);
-            }
-
-            /* sleep 300 to pass input buffers to sink */
-            Thread.sleep(300);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testInputVideo() {
-        String desc = "appsrc name=srcx ! " +
-                "video/x-raw,format=RGB,width=320,height=240,framerate=(fraction)0/1 ! " +
-                "tensor_converter ! tensor_sink name=sinkx";
-
-        /* For media format, set meta with exact buffer size. */
-        TensorsInfo info = new TensorsInfo();
-        /* input data : RGB 320x240 */
-        info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{3 * 320 * 240});
-
-        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;
-                    }
-
-                    /* check received data */
-                    TensorsInfo info = data.getTensorsInfo();
-                    NNStreamer.TensorType type = info.getTensorType(0);
-                    int[] dimension = info.getTensorDimension(0);
-
-                    if (type != NNStreamer.TensorType.UINT8) {
-                        mInvalidState = true;
-                    }
-
-                    if (dimension[0] != 3 || dimension[1] != 320 ||
-                        dimension[2] != 240 || dimension[3] != 1) {
-                        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(30);
-            }
-
-            /* sleep 200 to invoke */
-            Thread.sleep(200);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testInputAudio() {
-        String desc = "appsrc name=srcx ! " +
-                "audio/x-raw,format=S16LE,rate=16000,channels=1 ! " +
-                "tensor_converter frames-per-tensor=500 ! tensor_sink name=sinkx";
-
-        /* For media format, set meta with exact buffer size. */
-        TensorsInfo info = new TensorsInfo();
-        /* input data : 16k sample rate, mono, signed 16bit little-endian, 500 samples */
-        info.addTensorInfo(NNStreamer.TensorType.INT16, new int[]{500});
-
-        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;
-                    }
-
-                    /* check received data */
-                    TensorsInfo info = data.getTensorsInfo();
-                    NNStreamer.TensorType type = info.getTensorType(0);
-                    int[] dimension = info.getTensorDimension(0);
-
-                    if (type != NNStreamer.TensorType.INT16) {
-                        mInvalidState = true;
-                    }
-
-                    if (dimension[0] != 1 || dimension[1] != 500 ||
-                        dimension[2] != 1 || dimension[3] != 1) {
-                        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(30);
-            }
-
-            /* sleep 200 to invoke */
-            Thread.sleep(200);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testInputInvalidName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            /* start pipeline */
-            pipe.start();
-
-            pipe.inputData("invalid_src", TensorsData.allocate(info));
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInputNullName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            /* start pipeline */
-            pipe.start();
-
-            pipe.inputData(null, TensorsData.allocate(info));
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInputEmptyName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            /* start pipeline */
-            pipe.start();
-
-            pipe.inputData("", TensorsData.allocate(info));
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInputNullData_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            pipe.inputData("srcx", null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInputInvalidData_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{4,10,10,2});
-
-            TensorsData in = TensorsData.allocate(info);
-
-            /* push data with invalid size */
-            pipe.inputData("srcx", in);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSelectSwitch() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            /* register sink callback */
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            for (int i = 0; i < 15; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", TensorsData.allocate(info));
-                Thread.sleep(50);
-
-                if (i == 9) {
-                    /* select pad */
-                    pipe.selectSwitchPad("outs", "src_1");
-                }
-            }
-
-            /* sleep 300 to pass all input buffers to sink */
-            Thread.sleep(300);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertEquals(10, mReceived);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testGetSwitchPad() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* get pad list of output-selector */
-            String[] pads = pipe.getSwitchPads("outs");
-
-            assertEquals(2, pads.length);
-            assertEquals("src_0", pads[0]);
-            assertEquals("src_1", pads[1]);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testGetSwitchInvalidName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* get pad list with invalid switch name */
-            pipe.getSwitchPads("invalid_outs");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetSwitchNullName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* get pad list with null param */
-            pipe.getSwitchPads(null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetSwitchEmptyName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* get pad list with empty name */
-            pipe.getSwitchPads("");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSelectInvalidPad_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* select invalid pad name */
-            pipe.selectSwitchPad("outs", "invalid_src");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSelectNullPad_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* null pad name */
-            pipe.selectSwitchPad("outs", null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSelectEmptyPad_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* empty pad name */
-            pipe.selectSwitchPad("outs", "");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSelectNullSwitchName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* null switch name */
-            pipe.selectSwitchPad(null, "src_1");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSelectEmptySwitchName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "output-selector name=outs " +
-                "outs.src_0 ! tensor_sink name=sinkx async=false " +
-                "outs.src_1 ! tensor_sink async=false";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* empty switch name */
-            pipe.selectSwitchPad("", "src_1");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testControlValve() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tee name=t " +
-                "t. ! queue ! tensor_sink " +
-                "t. ! queue ! valve name=valvex ! tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,10,10,1});
-
-            /* register sink callback */
-            pipe.registerSinkCallback("sinkx", mSinkCb);
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            for (int i = 0; i < 15; i++) {
-                /* dummy input */
-                pipe.inputData("srcx", info.allocate());
-                Thread.sleep(50);
-
-                if (i == 9) {
-                    /* close valve */
-                    pipe.controlValve("valvex", false);
-                }
-            }
-
-            /* sleep 300 to pass all input buffers to sink */
-            Thread.sleep(300);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertEquals(10, mReceived);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testControlInvalidValve_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tee name=t " +
-                "t. ! queue ! tensor_sink " +
-                "t. ! queue ! valve name=valvex ! tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* control valve with invalid name */
-            pipe.controlValve("invalid_valve", false);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testControlNullValveName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tee name=t " +
-                "t. ! queue ! tensor_sink " +
-                "t. ! queue ! valve name=valvex ! tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* control valve with null name */
-            pipe.controlValve(null, false);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testControlEmptyValveName_n() {
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)2:10:10:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tee name=t " +
-                "t. ! queue ! tensor_sink " +
-                "t. ! queue ! valve name=valvex ! tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            /* start pipeline */
-            pipe.start();
-
-            /* control valve with empty name */
-            pipe.controlValve("", false);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetNullSurface() {
-        if (!Pipeline.isElementAvailable("glimagesink")) {
-            /* cannot run the test */
-            return;
-        }
-
-        String desc = "videotestsrc ! videoconvert ! glimagesink name=vsink";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.start();
-            Thread.sleep(500);
-
-            /* Setting null surface will release old window */
-            pipe.setSurface("vsink", null);
-
-            Thread.sleep(500);
-            pipe.stop();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSetSurfaceNullName_n() {
-        if (!Pipeline.isElementAvailable("glimagesink")) {
-            /* cannot run the test */
-            return;
-        }
-
-        String desc = "videotestsrc ! videoconvert ! glimagesink name=vsink";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.start();
-            Thread.sleep(500);
-
-            pipe.setSurface(null, null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetSurfaceEmptyName_n() {
-        if (!Pipeline.isElementAvailable("glimagesink")) {
-            /* cannot run the test */
-            return;
-        }
-
-        String desc = "videotestsrc ! videoconvert ! glimagesink name=vsink";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.start();
-            Thread.sleep(500);
-
-            pipe.setSurface("", null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetInvalidSurface_n() {
-        if (!Pipeline.isElementAvailable("glimagesink")) {
-            /* cannot run the test */
-            return;
-        }
-
-        /* invalid surface */
-        SurfaceView surfaceView = new SurfaceView(APITestCommon.getContext());
-        if (surfaceView.getHolder().getSurface().isValid()) {
-            fail();
-        }
-
-        String desc = "videotestsrc ! videoconvert ! glimagesink name=vsink";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            pipe.start();
-            Thread.sleep(500);
-
-            pipe.setSurface("vsink", surfaceView.getHolder());
-            fail();
-        } catch (Exception e) {
-            /* 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();
-        }
-    }
-
-    /**
-     * Run SNAP with Caffe model.
-     */
-    private void runSNAPCaffe(APITestCommon.SNAPComputingUnit CUnit) {
-        File[] models = APITestCommon.getSNAPCaffeModel();
-        String option = APITestCommon.getSNAPCaffeOption(CUnit);
-
-        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);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* 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(APITestCommon.SNAPComputingUnit.CPU);
-    }
-
-    @Test
-    public void testSNAPCaffeGPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSNAPCaffe(APITestCommon.SNAPComputingUnit.GPU);
-    }
-
-    /**
-     * Run SNAP with Tensorflow model.
-     */
-    private void runSNAPTensorflow(APITestCommon.SNAPComputingUnit CUnit) {
-        File[] model = APITestCommon.getSNAPTensorflowModel(CUnit);
-        String option = APITestCommon.getSNAPTensorflowOption(CUnit);
-        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=" + model[0].getAbsolutePath() + " " +
-                    "input=3:224:224:1 inputtype=float32 inputlayout=NHWC inputname=input " +
-                    "output=1001:1 outputtype=float32 outputlayout=NHWC outputname=MobilenetV1/Predictions/Reshape_1:0 " +
-                    "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, 4004)) {
-                            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);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSNAPTensorflowCPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSNAPTensorflow(APITestCommon.SNAPComputingUnit.CPU);
-    }
-
-    @Test
-    public void testSNAPTensorflowDSP() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
-            /* cannot run the test */
-            return;
-        }
-
-        if (!android.os.Build.HARDWARE.equals("qcom")) {
-            /*
-             * Tensorflow model using DSP runtime can only be executed on
-             * Snapdragon SoC. Cannot run this test on exynos.
-             */
-            return;
-        }
-
-        runSNAPTensorflow(APITestCommon.SNAPComputingUnit.DSP);
-    }
-
-    @Test
-    public void testSNAPTensorflowNPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
-            /* cannot run the test */
-            return;
-        }
-
-        if (!android.os.Build.HARDWARE.equals("qcom")) {
-            /*
-             * Tensorflow model using NPU runtime can only be executed on
-             * Snapdragon. Cannot run this test on exynos.
-             */
-            return;
-        }
-
-        runSNAPTensorflow(APITestCommon.SNAPComputingUnit.NPU);
-    }
-
-    @Test
-    public void testNNFWTFLite() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.NNFW)) {
-            /* cannot run the test */
-            return;
-        }
-
-        File model = APITestCommon.getTFLiteAddModel();
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)1:1:1:1,type=(string)float32,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=nnfw model=" + model.getAbsolutePath() + " ! " +
-                "tensor_sink name=sinkx";
-
-        try (Pipeline pipe = new Pipeline(desc)) {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{1,1,1,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;
-                    }
-
-                    ByteBuffer buffer = data.getTensorData(0);
-                    float expected = buffer.getFloat(0);
-
-                    /* check received data */
-                    if (expected != 3.5f) {
-                        mInvalidState = true;
-                    }
-
-                    mReceived++;
-                }
-            });
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            TensorsData input = info.allocate();
-
-            ByteBuffer buffer = input.getTensorData(0);
-            buffer.putFloat(0, 1.5f);
-
-            input.setTensorData(0, buffer);
-
-            pipe.inputData("srcx", input);
-
-            /* sleep 1000 to invoke */
-            Thread.sleep(1000);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSNPE() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        File model = APITestCommon.getSNPEModel();
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)3:299:299:1,type=(string)float32,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=snpe " + "model=" + model.getAbsolutePath() + " ! " +
-                "tensor_sink name=sinkx";
-
-        try (
-            Pipeline pipe = new Pipeline(desc);
-            TensorsInfo info = new TensorsInfo()
-        ) {
-            info.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{3,299,299,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, 4004)) {
-                            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);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    private void runSNPEMultipleOutput(String desc) {
-        try (
-                Pipeline pipe = new Pipeline(desc);
-                TensorsInfo info = new TensorsInfo()
-        ) {
-            info.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{3,300,300,1});
-
-            /* register sink callback */
-            pipe.registerSinkCallback("sinkx", new Pipeline.NewDataCallback() {
-                @Override
-                public void onNewDataReceived(TensorsData data) {
-                    if (data == null || data.getTensorsCount() != 2) {
-                        mInvalidState = true;
-                        return;
-                    }
-
-                    TensorsInfo info = data.getTensorsInfo();
-
-                    if (info == null || info.getTensorsCount() != 2) {
-                        mInvalidState = true;
-                    } else {
-                        ByteBuffer output = data.getTensorData(0);
-                        if (!APITestCommon.isValidBuffer(output, 1917 * 91 * 4)) {
-                            mInvalidState = true;
-                        }
-
-                        output = data.getTensorData(1);
-                        if (!APITestCommon.isValidBuffer(output, 1917 * 4 * 4)) {
-                            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 1000ms to invoke */
-            Thread.sleep(1000);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-
-    }
-
-    @Test
-    public void testSNPEMultipleOutputWithTensorInfo() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        File model = APITestCommon.getMultiOutputSNPEModel();
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)3:300:300:1,type=(string)float32,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=snpe " + "model=" + model.getAbsolutePath() +
-                " output=91:1917:1:1,4:1:1917:1 outputtype=float32,float32 outputname=concat,concat_1 ! " +
-                "tensor_sink name=sinkx";
-
-        runSNPEMultipleOutput(desc);
-    }
-
-    @Test
-    public void testSNPEMultipleOutputWithCustomProp() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        File model = APITestCommon.getMultiOutputSNPEModel();
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)3:300:300:1,type=(string)float32,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=snpe " + "model=" + model.getAbsolutePath() +
-                " custom=OutputLayer:concat;concat_1 ! " +
-                "tensor_sink name=sinkx";
-
-        runSNPEMultipleOutput(desc);
-    }
-
-    /**
-     * Run SNPE with inception model with given runtime.
-     */
-    private void runSNPEInception(String runtime) {
-        File model = APITestCommon.getSNPEModel();
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)3:299:299:1,type=(string)float32,framerate=(fraction)0/1 ! " +
-                "tensor_filter framework=snpe model=" + model.getAbsolutePath() +
-                " custom=Runtime:" + runtime + " ! " +
-                "tensor_sink name=sinkx";
-
-        /* expected label is measuring_cup (648) */
-        final int expected_label = 648;
-        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;
-                    }
-
-                    ByteBuffer buffer = data.getTensorData(0);
-                    int labelIndex = APITestCommon.getMaxScoreFloatBuffer(buffer, 1001);
-
-                    /* check label index (measuring cup) */
-                    if (labelIndex != expected_label) {
-                        mInvalidState = true;
-                    }
-
-                    mReceived++;
-                }
-            });
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            TensorsData in = APITestCommon.readRawImageDataSNPE();
-            pipe.inputData("srcx", in);
-
-            /* sleep 1000 msec to invoke */
-            Thread.sleep(1000);
-
-            /* stop pipeline */
-            pipe.stop();
-
-            /* check received data from sink */
-            assertFalse(mInvalidState);
-            assertTrue(mReceived > 0);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSNPEClassificationResultCPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSNPEInception("CPU");
-    }
-
-    @Test
-    public void testSNPEClassificationResultGPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSNPEInception("GPU");
-    }
-
-    @Test
-    public void testSNPEClassificationResultDSP() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSNPEInception("DSP");
-    }
-
-    @Test
-    public void testSNPEClassificationResultNPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSNPEInception("NPU");
-    }
-
-    @Test
-    public void testPytorchClassificationResult() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.PYTORCH)) {
-            /* cannot run the test */
-            return;
-        }
-
-        File model = APITestCommon.getPytorchModel();
-        String desc = "appsrc name=srcx ! " +
-                "other/tensor,dimension=(string)3:224:224:1,type=(string)uint8,framerate=(fraction)0/1 ! " +
-                "tensor_transform mode=dimchg option=0:2 ! " +
-                "tensor_transform mode=arithmetic option=typecast:float32,add:-127.5,div:127.5 ! " +
-                "tensor_filter framework=pytorch model=" + model.getAbsolutePath() + " " +
-                "input=224:224:3:1 inputtype=float32 output=1000:1 outputtype=float32 ! " +
-                "tensor_sink name=sinkx";
-
-        /* expected label is orange (950) */
-        final int expected_label = 950;
-
-        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;
-                    }
-
-                    ByteBuffer buffer = data.getTensorData(0);
-                    int labelIndex = APITestCommon.getMaxScoreFloatBuffer(buffer, 1000);
-
-                    /* check label index (orange) */
-                    if (labelIndex != expected_label) {
-                        mInvalidState = true;
-                    }
-                    mReceived++;
-                }
-            });
-
-            /* start pipeline */
-            pipe.start();
-
-            /* push input buffer */
-            TensorsData in = APITestCommon.readRawImageData();
-            pipe.inputData("srcx", in);
-
-            /* sleep 1000 to invoke */
-            Thread.sleep(1000);
-
-            /* 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/androidTest/java/org/nnsuite/nnstreamer/APITestSingleShot.java b/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestSingleShot.java
deleted file mode 100644 (file)
index 9d4a265..0000000
+++ /dev/null
@@ -1,985 +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 SingleShot.
- */
-@RunWith(AndroidJUnit4.class)
-public class APITestSingleShot {
-    @Rule
-    public GrantPermissionRule mPermissionRule = APITestCommon.grantPermissions();
-
-    @Before
-    public void setUp() {
-        APITestCommon.initNNStreamer();
-    }
-
-    @Test
-    public void testOptionsInvalidFW_n () {
-        try {
-            new SingleShot.Options(null, APITestCommon.getTFLiteImgModel());
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testOptionsUnknownFW_n () {
-        try {
-            new SingleShot.Options(NNStreamer.NNFWType.UNKNOWN, APITestCommon.getTFLiteImgModel());
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testOptionsInvalidModelFile_n () {
-        try {
-            File f = null;
-            new SingleShot.Options(NNStreamer.NNFWType.TENSORFLOW_LITE, f);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetInputInfo() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-            TensorsInfo info = single.getInputInfo();
-
-            /* input: uint8 3:224:224:1 */
-            assertEquals(1, info.getTensorsCount());
-            assertEquals(NNStreamer.TensorType.UINT8, info.getTensorType(0));
-            assertArrayEquals(new int[]{3,224,224,1}, info.getTensorDimension(0));
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testGetOutputInfo() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-            TensorsInfo info = single.getOutputInfo();
-
-            /* output: uint8 1001:1 */
-            assertEquals(1, info.getTensorsCount());
-            assertEquals(NNStreamer.TensorType.UINT8, info.getTensorType(0));
-            assertArrayEquals(new int[]{1001,1,1,1}, info.getTensorDimension(0));
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSetNullInputInfo_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-            single.setInputInfo(null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetInvalidInputInfo_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            TensorsInfo newInfo = new TensorsInfo();
-            newInfo.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,2,2,2});
-
-            single.setInputInfo(newInfo);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetInputInfo() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteAddModel());
-            TensorsInfo info = single.getInputInfo();
-
-            /* input: float32 with dimension 1 */
-            assertEquals(1, info.getTensorsCount());
-            assertEquals(NNStreamer.TensorType.FLOAT32, info.getTensorType(0));
-            assertArrayEquals(new int[]{1,1,1,1}, info.getTensorDimension(0));
-
-            TensorsInfo newInfo = new TensorsInfo();
-            newInfo.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{10});
-
-            single.setInputInfo(newInfo);
-
-            info = single.getInputInfo();
-            /* input: float32 with dimension 10 */
-            assertEquals(1, info.getTensorsCount());
-            assertEquals(NNStreamer.TensorType.FLOAT32, info.getTensorType(0));
-            assertArrayEquals(new int[]{10,1,1,1}, info.getTensorDimension(0));
-
-            info = single.getOutputInfo();
-            /* output: float32 with dimension 10 */
-            assertEquals(1, info.getTensorsCount());
-            assertEquals(NNStreamer.TensorType.FLOAT32, info.getTensorType(0));
-            assertArrayEquals(new int[]{10,1,1,1}, info.getTensorDimension(0));
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testInvoke() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-            TensorsInfo info = single.getInputInfo();
-
-            /* let's ignore timeout (set 10 sec) */
-            single.setTimeout(10000);
-
-            /* single-shot invoke */
-            for (int i = 0; i < 600; i++) {
-                /* dummy input */
-                TensorsData out = single.invoke(info.allocate());
-
-                /* output: uint8 1001:1 */
-                assertEquals(1, out.getTensorsCount());
-                assertEquals(1001, out.getTensorData(0).capacity());
-
-                Thread.sleep(30);
-            }
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    /**
-     * Run image classification and validate result.
-     */
-    private void runImageClassification(NNStreamer.NNFWType fw, String custom) {
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel(), fw, custom);
-
-            /* single-shot invoke */
-            TensorsData in = APITestCommon.readRawImageData();
-            TensorsData out = single.invoke(in);
-            int labelIndex = APITestCommon.getMaxScore(out.getTensorData(0));
-
-            /* check label index (orange) */
-            if (labelIndex != 951) {
-                fail();
-            }
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testClassificationResultTFLite() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runImageClassification(NNStreamer.NNFWType.TENSORFLOW_LITE, null);
-        runImageClassification(NNStreamer.NNFWType.TENSORFLOW_LITE, "Delegate:NNAPI");
-        runImageClassification(NNStreamer.NNFWType.TENSORFLOW_LITE, "Delegate:GPU");
-    }
-
-    @Test
-    public void testClassificationResultNNFW() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.NNFW)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runImageClassification(NNStreamer.NNFWType.NNFW, null);
-    }
-
-    /**
-     * Run dynamic invoke with add.tflite model.
-     */
-    private void runInvokeDynamic(NNStreamer.NNFWType fw) {
-        try {
-            File model = APITestCommon.getTFLiteAddModel();
-            SingleShot single = new SingleShot(model, fw);
-            TensorsInfo info = single.getInputInfo();
-
-            /* single-shot invoke */
-            for (int i = 1; i < 5; i++) {
-                /* change input information */
-                info.setTensorDimension(0, new int[]{i,1,1,1});
-                single.setInputInfo(info);
-
-                TensorsData input = TensorsData.allocate(info);
-                ByteBuffer inBuffer = input.getTensorData(0);
-
-                for (int j = 0; j < i; j++) {
-                    inBuffer.putFloat(j * 4, j + 1.5f);
-                }
-
-                input.setTensorData(0, inBuffer);
-
-                /* invoke */
-                TensorsData output = single.invoke(input);
-
-                /* output: float32 i:1:1:1 */
-                assertEquals(1, output.getTensorsCount());
-
-                ByteBuffer outBuffer = output.getTensorData(0);
-                assertEquals(i * Float.BYTES, outBuffer.capacity());
-
-                for (int j = 0; j < i; j++) {
-                    float expected = j + 3.5f;
-                    assertEquals(expected, outBuffer.getFloat(j * 4), 0.0f);
-                }
-
-                Thread.sleep(30);
-            }
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testInvokeDynamicTFLite() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runInvokeDynamic(NNStreamer.NNFWType.TENSORFLOW_LITE);
-    }
-
-    @Test
-    public void testInvokeDynamicNNFW() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.NNFW)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runInvokeDynamic(NNStreamer.NNFWType.NNFW);
-    }
-
-    @Test
-    public void testInvokeTimeout_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-            TensorsInfo info = single.getInputInfo();
-
-            /* timeout 1ms (not enough time to invoke the model) */
-            single.setTimeout(1);
-
-            /* dummy input */
-            single.invoke(TensorsData.allocate(info));
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testNullFile_n() {
-        try {
-            File f = null;
-            new SingleShot(f);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testNullFiles_n() {
-        try {
-            new SingleShot(null, null, null, NNStreamer.NNFWType.TENSORFLOW_LITE, null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInvalidFile_n() {
-        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
-        File model = new File(root + "/invalid_path/invalid.tflite");
-
-        try {
-            new SingleShot(model);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInvalidInputType_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        /* input: uint8 3:224:224:1 */
-        TensorsInfo info = new TensorsInfo();
-        info.addTensorInfo(NNStreamer.TensorType.UINT16, new int[]{3,224,224,1});
-
-        try {
-            new SingleShot(APITestCommon.getTFLiteImgModel(), info, null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInvalidInputDimension_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        /* input: uint8 3:224:224:1 */
-        TensorsInfo info = new TensorsInfo();
-        info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{2,224,224});
-
-        try {
-            new SingleShot(APITestCommon.getTFLiteImgModel(), info, null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInvalidOutputType_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        /* output: uint8 1001:1 */
-        TensorsInfo info = new TensorsInfo();
-        info.addTensorInfo(NNStreamer.TensorType.INT16, new int[]{1001,1});
-
-        try {
-            new SingleShot(APITestCommon.getTFLiteImgModel(), null, info);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInvalidOutputDimension_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        /* output: uint8 1001:1 */
-        TensorsInfo info = new TensorsInfo();
-        info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{1001,2,1,1});
-
-        try {
-            new SingleShot(APITestCommon.getTFLiteImgModel(), null, info);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInvokeNullData_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.invoke(null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testInvokeInvalidData_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        /* input data size: 3 * 224 * 224 */
-        TensorsInfo info = new TensorsInfo();
-        info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{100});
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.invoke(TensorsData.allocate(info));
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetInvalidTimeout_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.setTimeout(-1);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetInvalidPropertyName_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.getValue("");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetUnknownPropertyName_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.getValue("unknown_prop");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetNullPropertyName_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.getValue(null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetUnknownPropertyName_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.setValue("unknown_prop", "unknown");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetNullPropertyName_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.setValue(null, "ANY");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetEmptyPropertyName_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.setValue("", "ANY");
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetNullPropertyValue_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            single.setValue("inputlayout", null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetPropertyDimension() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteAddModel());
-
-            single.setValue("input", "5:1:1:1");
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testGetPropertyDimension() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.TENSORFLOW_LITE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            SingleShot single = new SingleShot(APITestCommon.getTFLiteImgModel());
-
-            assertEquals("3:224:224:1", single.getValue("input"));
-            assertEquals("1001:1:1:1", single.getValue("output"));
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    /**
-     * Run SNAP with Caffe model.
-     */
-    private void runSNAPCaffe(APITestCommon.SNAPComputingUnit CUnit) {
-        File[] models = APITestCommon.getSNAPCaffeModel();
-        String option = APITestCommon.getSNAPCaffeOption(CUnit);
-
-        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);
-
-            /* 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(APITestCommon.SNAPComputingUnit.CPU);
-    }
-
-    @Test
-    public void testSNAPCaffeGPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSNAPCaffe(APITestCommon.SNAPComputingUnit.GPU);
-    }
-
-    /**
-     * Run SNAP with Tensorflow model.
-     */
-    private void runSNAPTensorflow(APITestCommon.SNAPComputingUnit CUnit) {
-        File[] model = APITestCommon.getSNAPTensorflowModel(CUnit);
-        String option = APITestCommon.getSNAPTensorflowOption(CUnit);
-
-        try {
-            TensorsInfo in = new TensorsInfo();
-            in.addTensorInfo("input", NNStreamer.TensorType.FLOAT32, new int[]{3,224,224,1});
-
-            TensorsInfo out = new TensorsInfo();
-            out.addTensorInfo("MobilenetV1/Predictions/Reshape_1:0", NNStreamer.TensorType.FLOAT32, new int[]{1001, 1});
-
-            SingleShot single = new SingleShot(model, in, out, NNStreamer.NNFWType.SNAP, option);
-
-            /* let's ignore timeout (set 60 sec) */
-            single.setTimeout(60000);
-
-            /* single-shot invoke */
-            for (int i = 0; i < 10; i++) {
-                /* dummy input */
-                TensorsData output = single.invoke(in.allocate());
-
-                /* output: float32 1:1001 */
-                assertEquals(1, output.getTensorsCount());
-                assertEquals(4004, output.getTensorData(0).capacity());
-
-                Thread.sleep(30);
-            }
-
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSNAPTensorflowCPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
-            /* cannot run the test */
-            return;
-        }
-
-        runSNAPTensorflow(APITestCommon.SNAPComputingUnit.CPU);
-    }
-
-    @Test
-    public void testSNAPTensorflowDSP() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
-            /* cannot run the test */
-            return;
-        }
-
-        if (!android.os.Build.HARDWARE.equals("qcom")) {
-            /*
-             * Tensorflow model using DSP runtime can only be executed on
-             * Snapdragon SoC. Cannot run this test on exynos.
-             */
-            return;
-        }
-
-        runSNAPTensorflow(APITestCommon.SNAPComputingUnit.DSP);
-    }
-
-    @Test
-    public void testSNAPTensorflowNPU() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNAP)) {
-            /* cannot run the test */
-            return;
-        }
-
-        if (!android.os.Build.HARDWARE.equals("qcom")) {
-            /*
-             * Tensorflow model using NPU runtime can only be executed on
-             * Snapdragon. Cannot run this test on exynos.
-             */
-            return;
-        }
-
-        runSNAPTensorflow(APITestCommon.SNAPComputingUnit.NPU);
-    }
-
-    @Test
-    public void testNNFWTFLite() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.NNFW)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            File model = APITestCommon.getTFLiteAddModel();
-
-            SingleShot single = new SingleShot(model, NNStreamer.NNFWType.NNFW);
-            TensorsInfo in = single.getInputInfo();
-
-            /* let's ignore timeout (set 60 sec) */
-            single.setTimeout(60000);
-
-            /* single-shot invoke */
-            for (int i = 0; i < 5; i++) {
-                /* input data */
-                TensorsData input = in.allocate();
-
-                ByteBuffer buffer = input.getTensorData(0);
-                buffer.putFloat(0, i + 1.5f);
-
-                input.setTensorData(0, buffer);
-
-                /* invoke */
-                TensorsData output = single.invoke(input);
-
-                /* check output */
-                float expected = i + 3.5f;
-                assertEquals(expected, output.getTensorData(0).getFloat(0), 0.0f);
-
-                Thread.sleep(30);
-            }
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testNNFWOpenDir() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.NNFW)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            File model = new File(APITestCommon.getTFLiteAddModelPath());
-
-            new SingleShot(model, NNStreamer.NNFWType.NNFW);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testNNFWOpenInvalidDir_n() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.NNFW)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            File model = new File(APITestCommon.getTFLiteAddModelPath() + "/invaliddir");
-
-            new SingleShot(model, NNStreamer.NNFWType.NNFW);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSNPE() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        try {
-            File model = APITestCommon.getSNPEModel();
-
-            SingleShot single = new SingleShot(model, NNStreamer.NNFWType.SNPE);
-            TensorsInfo in = single.getInputInfo();
-
-            /* let's ignore timeout (set 60 sec) */
-            single.setTimeout(60000);
-
-            /* single-shot invoke */
-            for (int i = 0; i < 5; i++) {
-                /* input data */
-                TensorsData input = in.allocate();
-
-                /* invoke */
-                TensorsData output = single.invoke(input);
-
-                /* check output: 1 tensor (float32 1:1001) */
-                assertEquals(1, output.getTensorsCount());
-                assertEquals(4004, output.getTensorData(0).capacity());
-
-                Thread.sleep(30);
-            }
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSNPEClassificationResult() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
-            /* cannot run the test */
-            return;
-        }
-
-        /* expected label is measuring_cup (648) */
-        final int expected_label = 648;
-
-        try {
-            File model = APITestCommon.getSNPEModel();
-
-            SingleShot single = new SingleShot(model, NNStreamer.NNFWType.SNPE);
-
-            /* let's ignore timeout (set 10 sec) */
-            single.setTimeout(10000);
-
-            /* single-shot invoke */
-            TensorsData in = APITestCommon.readRawImageDataSNPE();
-            TensorsData out = single.invoke(in);
-            int labelIndex = APITestCommon.getMaxScoreFloatBuffer(out.getTensorData(0), 1001);
-
-            /* check label index (measuring cup) */
-            if (labelIndex != expected_label) {
-                fail();
-            }
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testPytorchClassificationResult() {
-        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.PYTORCH)) {
-            /* cannot run the test */
-            return;
-        }
-
-        /* expected label is orange (950) */
-        final int expected_label = 950;
-
-        try {
-            File model = APITestCommon.getPytorchModel();
-
-            TensorsInfo in = new TensorsInfo();
-            in.addTensorInfo("", NNStreamer.TensorType.FLOAT32, new int[]{224, 224, 3, 1});
-
-            TensorsInfo out = new TensorsInfo();
-            out.addTensorInfo("", NNStreamer.TensorType.FLOAT32, new int[]{1000, 1});
-
-            SingleShot single = new SingleShot(new File[]{model}, in, out, NNStreamer.NNFWType.PYTORCH, "");
-
-            /* invoke */
-            TensorsData output = single.invoke(APITestCommon.readRawImageDataPytorch());
-
-            int labelIndex = APITestCommon.getMaxScoreFloatBuffer(output.getTensorData(0), 1000);
-
-            /* check label index (orange) */
-            if (labelIndex != expected_label) {
-                fail();
-            }
-
-            single.close();
-        } catch (Exception e) {
-            fail();
-        }
-    }
-}
diff --git a/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestTensorsData.java b/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestTensorsData.java
deleted file mode 100644 (file)
index f9932b3..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-package org.nnsuite.nnstreamer;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import static org.junit.Assert.*;
-
-/**
- * Testcases for TensorsData.
- */
-@RunWith(AndroidJUnit4.class)
-public class APITestTensorsData {
-    private TensorsData mData;
-
-    @Before
-    public void setUp() {
-        APITestCommon.initNNStreamer();
-
-        TensorsInfo info = new TensorsInfo();
-
-        info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{100});
-        info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{200});
-        info.addTensorInfo(NNStreamer.TensorType.UINT8, new int[]{300});
-
-        mData = TensorsData.allocate(info);
-    }
-
-    @After
-    public void tearDown() {
-        mData.close();
-    }
-
-    @Test
-    public void testAllocateByteBuffer() {
-        try {
-            ByteBuffer buffer = TensorsData.allocateByteBuffer(300);
-
-            assertTrue(APITestCommon.isValidBuffer(buffer, 300));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testAllocate() {
-        try {
-            TensorsInfo info = new TensorsInfo();
-
-            info.addTensorInfo(NNStreamer.TensorType.INT16, new int[]{2});
-            info.addTensorInfo(NNStreamer.TensorType.UINT16, new int[]{2,2});
-            info.addTensorInfo(NNStreamer.TensorType.UINT32, new int[]{2,2,2});
-
-            TensorsData data = TensorsData.allocate(info);
-
-            /* index 0: 2 int16 */
-            assertTrue(APITestCommon.isValidBuffer(data.getTensorData(0), 4));
-
-            /* index 1: 2:2 uint16 */
-            assertTrue(APITestCommon.isValidBuffer(data.getTensorData(1), 8));
-
-            /* index 2: 2:2:2 uint32 */
-            assertTrue(APITestCommon.isValidBuffer(data.getTensorData(2), 32));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testAllocateEmptyInfo_n() {
-        try {
-            TensorsInfo info = new TensorsInfo();
-
-            TensorsData.allocate(info);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testAllocateNullInfo_n() {
-        try {
-            TensorsData.allocate(null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetData() {
-        try {
-            assertTrue(APITestCommon.isValidBuffer(mData.getTensorData(0), 100));
-            assertTrue(APITestCommon.isValidBuffer(mData.getTensorData(1), 200));
-            assertTrue(APITestCommon.isValidBuffer(mData.getTensorData(2), 300));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSetData() {
-        try {
-            ByteBuffer buffer = TensorsData.allocateByteBuffer(200);
-            mData.setTensorData(1, buffer);
-
-            assertEquals(3, mData.getTensorsCount());
-            assertTrue(APITestCommon.isValidBuffer(mData.getTensorData(0), 100));
-            assertTrue(APITestCommon.isValidBuffer(mData.getTensorData(1), 200));
-            assertTrue(APITestCommon.isValidBuffer(mData.getTensorData(2), 300));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testSetNullByteBuffer_n() {
-        try {
-            ByteBuffer buffer = null;
-
-            mData.setTensorData(0, buffer);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetInvalidOrderByteBuffer_n() {
-        try {
-            /* big-endian byte order */
-            ByteBuffer buffer = ByteBuffer.allocateDirect(100);
-
-            mData.setTensorData(0, buffer);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetNonDirectByteBuffer_n() {
-        try {
-            /* non-direct byte buffer */
-            ByteBuffer buffer = ByteBuffer.allocate(100).order(ByteOrder.nativeOrder());
-
-            mData.setTensorData(0, buffer);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetInvalidIndex_n() {
-        try {
-            mData.getTensorData(5);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetInvalidIndex_n() {
-        try {
-            ByteBuffer buffer = TensorsData.allocateByteBuffer(500);
-
-            mData.setTensorData(5, buffer);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testSetInvalidSizeByteBuffer_n() {
-        try {
-            ByteBuffer buffer = TensorsData.allocateByteBuffer(500);
-
-            mData.setTensorData(1, buffer);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testAllocateInvalidSize_n() {
-        try {
-            TensorsData.allocateByteBuffer(-1);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testAllocateZeroSize_n() {
-        try {
-            TensorsData.allocateByteBuffer(0);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testGetInfo() {
-        try {
-            TensorsInfo info = new TensorsInfo();
-            info.addTensorInfo("name1", NNStreamer.TensorType.INT64, new int[]{10,1,1,1});
-            info.addTensorInfo("name2", NNStreamer.TensorType.UINT64, new int[]{20,1,1,1});
-
-            /* allocate data, info is cloned */
-            TensorsData data = TensorsData.allocate(info);
-
-            /* update info */
-            info.setTensorName(0, "test1");
-            info.setTensorType(0, NNStreamer.TensorType.INT16);
-            info.setTensorDimension(0, new int[]{1,1,1,1});
-
-            info.setTensorName(1, "test2");
-            info.setTensorType(1, NNStreamer.TensorType.UINT16);
-            info.setTensorDimension(1, new int[]{2,2,1,1});
-
-            info.addTensorInfo("test3", NNStreamer.TensorType.FLOAT64, new int[]{3,3,3,1});
-
-            assertEquals(3, info.getTensorsCount());
-
-            /* check cloned info */
-            TensorsInfo cloned = data.getTensorsInfo();
-
-            assertEquals(2, cloned.getTensorsCount());
-
-            assertEquals("name1", cloned.getTensorName(0));
-            assertEquals(NNStreamer.TensorType.INT64, cloned.getTensorType(0));
-            assertArrayEquals(new int[]{10,1,1,1}, cloned.getTensorDimension(0));
-
-            assertEquals("name2", cloned.getTensorName(1));
-            assertEquals(NNStreamer.TensorType.UINT64, cloned.getTensorType(1));
-            assertArrayEquals(new int[]{20,1,1,1}, cloned.getTensorDimension(1));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-}
diff --git a/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestTensorsInfo.java b/api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestTensorsInfo.java
deleted file mode 100644 (file)
index 738c4b5..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-package org.nnsuite.nnstreamer;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Testcases for TensorsInfo.
- */
-@RunWith(AndroidJUnit4.class)
-public class APITestTensorsInfo {
-    private TensorsInfo mInfo;
-
-    @Before
-    public void setUp() {
-        APITestCommon.initNNStreamer();
-        mInfo = new TensorsInfo();
-    }
-
-    @After
-    public void tearDown() {
-        mInfo.close();
-    }
-
-    @Test
-    public void testAddInfo() {
-        try {
-            mInfo.addTensorInfo("name1", NNStreamer.TensorType.INT8, new int[]{1});
-            assertEquals(1, mInfo.getTensorsCount());
-
-            mInfo.addTensorInfo("name2", NNStreamer.TensorType.UINT8, new int[]{2,2});
-            assertEquals(2, mInfo.getTensorsCount());
-
-            mInfo.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{3,3,3});
-            assertEquals(3, mInfo.getTensorsCount());
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testGetInfo() {
-        try {
-            testAddInfo();
-
-            assertEquals("name1", mInfo.getTensorName(0));
-            assertEquals(NNStreamer.TensorType.INT8, mInfo.getTensorType(0));
-            assertArrayEquals(new int[]{1,1,1,1}, mInfo.getTensorDimension(0));
-
-            assertEquals("name2", mInfo.getTensorName(1));
-            assertEquals(NNStreamer.TensorType.UINT8, mInfo.getTensorType(1));
-            assertArrayEquals(new int[]{2,2,1,1}, mInfo.getTensorDimension(1));
-
-            assertNull(mInfo.getTensorName(2));
-            assertEquals(NNStreamer.TensorType.FLOAT32, mInfo.getTensorType(2));
-            assertArrayEquals(new int[]{3,3,3,1}, mInfo.getTensorDimension(2));
-
-            assertEquals(3, mInfo.getTensorsCount());
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testClone() {
-        try {
-            testAddInfo();
-
-            /* clone */
-            TensorsInfo cloned = mInfo.clone();
-
-            /* update info */
-            mInfo.setTensorName(0, "updated1");
-            mInfo.setTensorType(0, NNStreamer.TensorType.INT16);
-            mInfo.setTensorDimension(0, new int[]{10,1,1,1});
-
-            mInfo.setTensorName(1, "updated2");
-            mInfo.setTensorType(1, NNStreamer.TensorType.UINT16);
-            mInfo.setTensorDimension(1, new int[]{20,1,1,1});
-
-            mInfo.setTensorName(2, "updated3");
-            mInfo.setTensorType(2, NNStreamer.TensorType.FLOAT64);
-            mInfo.setTensorDimension(2, new int[]{30,1,1,1});
-
-            mInfo.addTensorInfo("updated4", NNStreamer.TensorType.INT64, new int[]{40,1,1,1});
-
-            /* check cloned info */
-            assertEquals("name1", cloned.getTensorName(0));
-            assertEquals(NNStreamer.TensorType.INT8, cloned.getTensorType(0));
-            assertArrayEquals(new int[]{1,1,1,1}, cloned.getTensorDimension(0));
-
-            assertEquals("name2", cloned.getTensorName(1));
-            assertEquals(NNStreamer.TensorType.UINT8, cloned.getTensorType(1));
-            assertArrayEquals(new int[]{2,2,1,1}, cloned.getTensorDimension(1));
-
-            assertNull(cloned.getTensorName(2));
-            assertEquals(NNStreamer.TensorType.FLOAT32, cloned.getTensorType(2));
-            assertArrayEquals(new int[]{3,3,3,1}, cloned.getTensorDimension(2));
-
-            assertEquals(3, cloned.getTensorsCount());
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testGetSize() {
-        try {
-            testAddInfo();
-
-            /* index 0: 1 int8 */
-            assertEquals(1, mInfo.getTensorSize(0));
-
-            /* index 1: 2:2 uint8 */
-            assertEquals(4, mInfo.getTensorSize(1));
-
-            /* index 2: 3:3:3 float32 */
-            assertEquals(108, mInfo.getTensorSize(2));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testAllocate() {
-        try {
-            testAddInfo();
-
-            TensorsData data = mInfo.allocate();
-
-            assertEquals(3, data.getTensorsCount());
-            assertEquals(1, data.getTensorData(0).capacity());
-            assertEquals(4, data.getTensorData(1).capacity());
-            assertEquals(108, data.getTensorData(2).capacity());
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testAllocateEmpty_n() {
-        try {
-            TensorsInfo info = new TensorsInfo();
-
-            info.allocate();
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testUpdateInfo() {
-        try {
-            testAddInfo();
-
-            mInfo.setTensorName(2, "name3");
-            assertEquals("name1", mInfo.getTensorName(0));
-            assertEquals("name2", mInfo.getTensorName(1));
-            assertEquals("name3", mInfo.getTensorName(2));
-
-            mInfo.setTensorType(2, NNStreamer.TensorType.INT64);
-            assertEquals(NNStreamer.TensorType.INT8, mInfo.getTensorType(0));
-            assertEquals(NNStreamer.TensorType.UINT8, mInfo.getTensorType(1));
-            assertEquals(NNStreamer.TensorType.INT64, mInfo.getTensorType(2));
-
-            mInfo.setTensorDimension(2, new int[]{2,3});
-            assertArrayEquals(new int[]{1,1,1,1}, mInfo.getTensorDimension(0));
-            assertArrayEquals(new int[]{2,2,1,1}, mInfo.getTensorDimension(1));
-            assertArrayEquals(new int[]{2,3,1,1}, mInfo.getTensorDimension(2));
-        } catch (Exception e) {
-            fail();
-        }
-    }
-
-    @Test
-    public void testAddUnknownType_n() {
-        try {
-            mInfo.addTensorInfo(NNStreamer.TensorType.UNKNOWN, new int[]{2,2,2,2});
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-
-        assertEquals(0, mInfo.getTensorsCount());
-    }
-
-    @Test
-    public void testAddInvalidRank_n() {
-        try {
-            mInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{2,2,2,2,2});
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-
-        assertEquals(0, mInfo.getTensorsCount());
-    }
-
-    @Test
-    public void testAddInvalidDimension_n() {
-        try {
-            mInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{1,1,-1});
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-
-        assertEquals(0, mInfo.getTensorsCount());
-    }
-
-    @Test
-    public void testAddNullDimension_n() {
-        try {
-            mInfo.addTensorInfo(NNStreamer.TensorType.UINT8, null);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-
-        assertEquals(0, mInfo.getTensorsCount());
-    }
-
-    @Test
-    public void testGetInvalidIndex_n() {
-        try {
-            mInfo.getTensorType(0);
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-
-    @Test
-    public void testAddMaxInfo_n() {
-        try {
-            for (int i = 0; i <= NNStreamer.TENSOR_SIZE_LIMIT; i++) {
-                mInfo.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{2,2,2,2});
-            }
-            fail();
-        } catch (Exception e) {
-            /* expected */
-        }
-    }
-}
diff --git a/api/android/api/src/main/AndroidManifest.xml b/api/android/api/src/main/AndroidManifest.xml
deleted file mode 100644 (file)
index 9b0a6f1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.nnsuite.nnstreamer" >
-
-    <uses-feature android:glEsVersion="0x00020000"/>
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-
-    <application
-        android:extractNativeLibs="true"
-        android:largeHeap="true" >
-    </application>
-</manifest>
diff --git a/api/android/api/src/main/java/org/nnsuite/nnstreamer/CustomFilter.java b/api/android/api/src/main/java/org/nnsuite/nnstreamer/CustomFilter.java
deleted file mode 100644 (file)
index 6649600..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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.
- */
-
-package org.nnsuite.nnstreamer;
-
-import android.support.annotation.NonNull;
-
-/**
- * Provides interfaces to create a custom-filter in the pipeline.<br>
- * <br>
- * To register a new custom-filter, an application should call
- * {@link #create(String, TensorsInfo, TensorsInfo, Callback)}
- * before constructing the pipeline.
- */
-public final class CustomFilter implements AutoCloseable {
-    private long mHandle = 0;
-    private String mName = null;
-    private Callback mCallback = null;
-
-    private native long nativeInitialize(String name, TensorsInfo in, TensorsInfo out);
-    private native void nativeDestroy(long handle);
-
-    /**
-     * Interface definition for a callback to be invoked while processing the pipeline.
-     *
-     * @see #create(String, TensorsInfo, TensorsInfo, Callback)
-     */
-    public interface Callback {
-        /**
-         * Called synchronously while processing the pipeline.
-         *
-         * NNStreamer filter invokes the given custom-filter callback while processing the pipeline.
-         * Note that, if it is unnecessary to execute the input data, return null to drop the buffer.
-         *
-         * @param in The input data (a single frame, tensor/tensors)
-         *
-         * @return The output data (a single frame, tensor/tensors)
-         */
-        TensorsData invoke(TensorsData in);
-    }
-
-    /**
-     * Creates new custom-filter with input and output tensors information.
-     *
-     * NNStreamer processes the tensors with 'custom-easy' framework which can execute without the model file.
-     * Note that if given name is duplicated in the pipeline or same name already exists,
-     * the registration will be failed and throw an exception.
-     *
-     * @param name     The name of custom-filter
-     * @param in       The input tensors information
-     * @param out      The output tensors information
-     * @param callback The function to be called while processing the pipeline
-     *
-     * @return {@link CustomFilter} instance
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to initialize custom-filter
-     */
-    public static CustomFilter create(@NonNull String name, @NonNull TensorsInfo in,
-            @NonNull TensorsInfo out, @NonNull Callback callback) {
-        return new CustomFilter(name, in, out, callback);
-    }
-
-    /**
-     * Gets the name of custom-filter.
-     *
-     * @return The name of custom-filter
-     */
-    public String getName() {
-        return mName;
-    }
-
-    /**
-     * Internal constructor to create and register a custom-filter.
-     *
-     * @param name     The name of custom-filter
-     * @param in       The input tensors information
-     * @param out      The output tensors information
-     * @param callback The function to be called while processing the pipeline
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to initialize custom-filter
-     */
-    private CustomFilter(String name, TensorsInfo in, TensorsInfo out, Callback callback) {
-        if (name == null) {
-            throw new IllegalArgumentException("Given name is null");
-        }
-
-        if (in == null || out == null) {
-            throw new IllegalArgumentException("Given info is null");
-        }
-
-        if (callback == null) {
-            throw new IllegalArgumentException("Given callback is null");
-        }
-
-        mHandle = nativeInitialize(name, in, out);
-        if (mHandle == 0) {
-            throw new IllegalStateException("Failed to initialize custom-filter " + name);
-        }
-
-        mName = name;
-        mCallback = callback;
-    }
-
-    /**
-     * Internal method called from native while processing the pipeline.
-     */
-    private TensorsData invoke(TensorsData in) {
-        TensorsData out = null;
-
-        if (mCallback != null) {
-            out = mCallback.invoke(in);
-        }
-
-        return out;
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    @Override
-    public void close() {
-        if (mHandle != 0) {
-            nativeDestroy(mHandle);
-            mHandle = 0;
-        }
-    }
-
-    /**
-     * Private constructor to prevent the instantiation.
-     */
-    private CustomFilter() {}
-}
diff --git a/api/android/api/src/main/java/org/nnsuite/nnstreamer/NNStreamer.java b/api/android/api/src/main/java/org/nnsuite/nnstreamer/NNStreamer.java
deleted file mode 100644 (file)
index 7c753ca..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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.
- */
-
-package org.nnsuite.nnstreamer;
-
-import android.content.Context;
-import android.os.Build;
-
-import org.freedesktop.gstreamer.GStreamer;
-
-import java.util.Locale;
-
-/**
- * Defines the types and limits in NNStreamer.<br>
- * To use NNStreamer, an application should call {@link #initialize(Context)} with its context.<br>
- * <br>
- * NNStreamer is a set of GStreamer plugins that allow GStreamer developers to adopt neural network models easily and efficiently
- * and neural network developers to manage stream pipelines and their filters easily and efficiently.<br>
- * <br>
- * Note that, to open a machine learning model in the storage,
- * the permission {@code Manifest.permission.READ_EXTERNAL_STORAGE} is required before constructing the pipeline.
- * <br>
- * See <a href="https://github.com/nnstreamer/nnstreamer">NNStreamer repository</a> for the details.
- */
-public final class NNStreamer {
-    /**
-     * The maximum rank that NNStreamer supports.
-     */
-    public static final int TENSOR_RANK_LIMIT = 4;
-
-    /**
-     * The maximum number of tensor that {@link TensorsData} instance may have.
-     */
-    public static final int TENSOR_SIZE_LIMIT = 16;
-
-    /**
-     * The enumeration for supported frameworks in NNStreamer.
-     *
-     * @see #isAvailable(NNFWType)
-     */
-    public enum NNFWType {
-        /**
-         * <a href="https://www.tensorflow.org/lite">TensorFlow Lite</a> is an open source
-         * deep learning framework for on-device inference.
-         */
-        TENSORFLOW_LITE,
-        /**
-         * SNAP (Samsung Neural Acceleration Platform)
-         * supports <a href="https://developer.samsung.com/neural">Samsung Neural SDK</a>
-         * (Version 2.0, run only on Samsung devices).<br>
-         * To construct a pipeline with SNAP, developer should set the custom option string
-         * to specify the neural network and data format.<br>
-         * <br>
-         * Custom options<br>
-         * - ModelFWType: the type of model (TensorFlow/Caffe)<br>
-         * - ExecutionDataType: the execution data type for SNAP (default float32)<br>
-         * - ComputingUnit: the computing unit to execute the model (default CPU)<br>
-         * - CpuThreadCount: the number of CPU threads to be executed (optional, default 4 if ComputingUnit is CPU)<br>
-         * - GpuCacheSource: the absolute path to GPU Kernel caching (mandatory if ComputingUnit is GPU)
-         */
-        SNAP,
-        /**
-         * NNFW is on-device neural network inference framework, which is developed by SR (Samsung Research).<br>
-         * See <a href="https://github.com/Samsung/ONE">ONE (On-device Neural Engine) repository</a> for the details.
-         */
-        NNFW,
-        /**
-         * <a href="https://developer.qualcomm.com/docs/snpe/index.html">SNPE</a> (Snapdragon Neural Processing Engine)
-         * is a Qualcomm Snapdragon software accelerated runtime for the execution of deep neural networks.<br>
-         * <br>
-         * Custom options<br>
-         * - Runtime: the computing unit to execute the model (default CPU)<br>
-         * - CPUFallback: CPU fallback mode (default false)
-         */
-        SNPE,
-        /**
-         * <a href="https://pytorch.org/mobile/home/">PyTorch Mobile</a>
-         * is an on-device solution for the open source machine learning framework, PyTorch.
-         */
-        PYTORCH,
-        /**
-         * Unknown framework (usually error)
-         */
-        UNKNOWN
-    }
-
-    /**
-     * The enumeration for possible data type of tensor in NNStreamer.
-     */
-    public enum TensorType {
-        /** Integer 32bit */ INT32,
-        /** Unsigned integer 32bit */ UINT32,
-        /** Integer 16bit */ INT16,
-        /** Unsigned integer 16bit */ UINT16,
-        /** Integer 8bit */ INT8,
-        /** Unsigned integer 8bit */ UINT8,
-        /** Float 64bit */ FLOAT64,
-        /** Float 32bit */ FLOAT32,
-        /** Integer 64bit */ INT64,
-        /** Unsigned integer 64bit */ UINT64,
-        /** Unknown data type (usually error) */ UNKNOWN
-    }
-
-    private static native boolean nativeInitialize(Context context);
-    private static native boolean nativeCheckNNFWAvailability(int fw);
-    private static native String nativeGetVersion();
-
-    /**
-     * Initializes GStreamer and NNStreamer, registering the plugins and loading necessary libraries.
-     *
-     * @param context The application context
-     *
-     * @return true if successfully initialized
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     */
-    public static boolean initialize(Context context) {
-        if (context == null) {
-            throw new IllegalArgumentException("Given context is invalid");
-        }
-
-        try {
-            System.loadLibrary("gstreamer_android");
-            System.loadLibrary("nnstreamer-native");
-
-            GStreamer.init(context);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return false;
-        }
-
-        return nativeInitialize(context);
-    }
-
-    /**
-     * Checks the neural network framework is available.
-     *
-     * @param fw The neural network framework
-     *
-     * @return true if the neural network framework is available
-     */
-    public static boolean isAvailable(NNFWType fw) {
-        boolean available = nativeCheckNNFWAvailability(fw.ordinal());
-
-        /* sub-plugin for given framework is available */
-        if (available) {
-            String manufacturer = Build.MANUFACTURER.toLowerCase(Locale.getDefault());
-            String hardware = Build.HARDWARE.toLowerCase(Locale.getDefault());
-
-            switch (fw) {
-                case SNPE:
-                    if (!hardware.startsWith("qcom")) {
-                        available = false;
-                    }
-                    break;
-                case SNAP:
-                    if (!manufacturer.equals("samsung") ||
-                        !(hardware.startsWith("qcom") || hardware.startsWith("exynos"))) {
-                        available = false;
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        return available;
-    }
-
-    /**
-     * Gets the version string of NNStreamer.
-     *
-     * @return The version string
-     */
-    public static String getVersion() {
-        return nativeGetVersion();
-    }
-
-    /**
-     * Private constructor to prevent the instantiation.
-     */
-    private NNStreamer() {}
-}
diff --git a/api/android/api/src/main/java/org/nnsuite/nnstreamer/Pipeline.java b/api/android/api/src/main/java/org/nnsuite/nnstreamer/Pipeline.java
deleted file mode 100644 (file)
index bec05df..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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.
- */
-
-package org.nnsuite.nnstreamer;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * Provides interfaces to create and execute stream pipelines with neural networks.<br>
- * <br>
- * {@link Pipeline} allows the following operations with NNStreamer:<br>
- * - Create a stream pipeline with NNStreamer plugins, GStreamer plugins.<br>
- * - Interfaces to push data to the pipeline from the application.<br>
- * - Interfaces to pull data from the pipeline to the application.<br>
- * - Interfaces to start/stop/destroy the pipeline.<br>
- * - Interfaces to control switches and valves in the pipeline.<br>
- */
-public final class Pipeline implements AutoCloseable {
-    private long mHandle = 0;
-    private HashMap<String, ArrayList<NewDataCallback>> mSinkCallbacks = new HashMap<>();
-    private StateChangeCallback mStateCallback = null;
-
-    private static native boolean nativeCheckElementAvailability(String element);
-    private native long nativeConstruct(String description, boolean addStateCb);
-    private native void nativeDestroy(long handle);
-    private native boolean nativeStart(long handle);
-    private native boolean nativeStop(long handle);
-    private native int nativeGetState(long handle);
-    private native boolean nativeInputData(long handle, String name, TensorsData data);
-    private native String[] nativeGetSwitchPads(long handle, String name);
-    private native boolean nativeSelectSwitchPad(long handle, String name, String pad);
-    private native boolean nativeControlValve(long handle, String name, boolean open);
-    private native boolean nativeAddSinkCallback(long handle, String name);
-    private native boolean nativeRemoveSinkCallback(long handle, String name);
-    private native boolean nativeInitializeSurface(long handle, String name, Object surface);
-    private native boolean nativeFinalizeSurface(long handle, String name);
-
-    /**
-     * Interface definition for a callback to be invoked when a sink node receives new data.
-     *
-     * @see #registerSinkCallback(String, NewDataCallback)
-     */
-    public interface NewDataCallback {
-        /**
-         * Called when a sink node receives new data.
-         *
-         * If an application wants to accept data outputs of an NNStreamer stream, use this callback to get data from the stream.
-         * Note that this is synchronously called and the buffer may be deallocated after the callback is finished.
-         * Thus, if you need the data afterwards, copy the data to another buffer and return fast.
-         * Do not spend too much time in the callback. It is recommended to use very small tensors at sinks.
-         *
-         * @param data The output data (a single frame, tensor/tensors)
-         */
-        void onNewDataReceived(TensorsData data);
-    }
-
-    /**
-     * Interface definition for a callback to be invoked when the pipeline state is changed.
-     * This callback can be registered only when constructing the pipeline.
-     *
-     * @see State
-     * @see #start()
-     * @see #stop()
-     * @see Pipeline#Pipeline(String, StateChangeCallback)
-     */
-    public interface StateChangeCallback {
-        /**
-         * Called when the pipeline state is changed.
-         *
-         * If an application wants to get the change of pipeline state, use this callback.
-         * This callback can be registered when constructing the pipeline.
-         * This is synchronously called, so do not spend too much time in the callback.
-         *
-         * @param state The changed state
-         */
-        void onStateChanged(Pipeline.State state);
-    }
-
-    /**
-     * The enumeration for pipeline state.
-     * Refer to <a href="https://gstreamer.freedesktop.org/documentation/plugin-development/basics/states.html">GStreamer states</a> for the details.
-     */
-    public enum State {
-        /**
-         * Unknown state.
-         */
-        UNKNOWN,
-        /**
-         * Initial state of the pipeline.
-         */
-        NULL,
-        /**
-         * The pipeline is ready to go to PAUSED.
-         */
-        READY,
-        /**
-         * The pipeline is stopped, ready to accept and process data.
-         */
-        PAUSED,
-        /**
-         * The pipeline is started and the data is flowing.
-         */
-        PLAYING
-    }
-
-    /**
-     * Creates a new {@link Pipeline} instance with the given pipeline description.
-     *
-     * @param description The pipeline description. Refer to GStreamer manual or
-     *                    <a href="https://github.com/nnstreamer/nnstreamer">NNStreamer</a> documentation for examples and the grammar.
-     *
-     * @throws IllegalArgumentException if given param is null
-     * @throws IllegalStateException if failed to construct the pipeline
-     */
-    public Pipeline(@NonNull String description) {
-        this(description, null);
-    }
-
-    /**
-     * Creates a new {@link Pipeline} instance with the given pipeline description.
-     *
-     * @param description The pipeline description. Refer to GStreamer manual or
-     *                    <a href="https://github.com/nnstreamer/nnstreamer">NNStreamer</a> documentation for examples and the grammar.
-     * @param callback    The function to be called when the pipeline state is changed.
-     *                    You may set null if it is not required.
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to construct the pipeline
-     */
-    public Pipeline(@NonNull String description, @Nullable StateChangeCallback callback) {
-        if (description == null || description.isEmpty()) {
-            throw new IllegalArgumentException("Given description is invalid");
-        }
-
-        mStateCallback = callback;
-
-        mHandle = nativeConstruct(description, (callback != null));
-        if (mHandle == 0) {
-            throw new IllegalStateException("Failed to construct the pipeline");
-        }
-    }
-
-    /**
-     * Checks the element is registered and available on the pipeline.
-     *
-     * @param element The name of GStreamer element
-     *
-     * @return true if the element is available
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     */
-    public static boolean isElementAvailable(@NonNull String element) {
-        if (element == null || element.isEmpty()) {
-            throw new IllegalArgumentException("Given element is invalid");
-        }
-
-        return nativeCheckElementAvailability(element);
-    }
-
-    /**
-     * Starts the pipeline, asynchronously.
-     * The pipeline state would be changed to {@link State#PLAYING}.
-     * If you need to get the changed state, add a callback while constructing a pipeline.
-     *
-     * @throws IllegalStateException if failed to start the pipeline
-     *
-     * @see State
-     * @see StateChangeCallback
-     */
-    public void start() {
-        checkPipelineHandle();
-
-        if (!nativeStart(mHandle)) {
-            throw new IllegalStateException("Failed to start the pipeline");
-        }
-    }
-
-    /**
-     * Stops the pipeline, asynchronously.
-     * The pipeline state would be changed to {@link State#PAUSED}.
-     * If you need to get the changed state, add a callback while constructing a pipeline.
-     *
-     * @throws IllegalStateException if failed to stop the pipeline
-     *
-     * @see State
-     * @see StateChangeCallback
-     */
-    public void stop() {
-        checkPipelineHandle();
-
-        if (!nativeStop(mHandle)) {
-            throw new IllegalStateException("Failed to stop the pipeline");
-        }
-    }
-
-    /**
-     * Gets the state of pipeline.
-     *
-     * @return The state of pipeline
-     *
-     * @throws IllegalStateException if the pipeline is not constructed
-     *
-     * @see State
-     * @see StateChangeCallback
-     */
-    public State getState() {
-        checkPipelineHandle();
-
-        return convertPipelineState(nativeGetState(mHandle));
-    }
-
-    /**
-     * Adds an input data frame to source node.
-     *
-     * @param name The name of source node
-     * @param data The input data (a single frame, tensor/tensors)
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to push data to source node
-     */
-    public void inputData(@NonNull String name, @NonNull TensorsData data) {
-        checkPipelineHandle();
-
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given name is invalid");
-        }
-
-        if (data == null) {
-            throw new IllegalArgumentException("Given data is null");
-        }
-
-        if (!nativeInputData(mHandle, name, data)) {
-            throw new IllegalStateException("Failed to push data to source node " + name);
-        }
-    }
-
-    /**
-     * Gets the pad names of a switch.
-     *
-     * @param name The name of switch node
-     *
-     * @return The list of pad names
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to get the list of pad names
-     */
-    public String[] getSwitchPads(@NonNull String name) {
-        checkPipelineHandle();
-
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given name is invalid");
-        }
-
-        String[] pads = nativeGetSwitchPads(mHandle, name);
-
-        if (pads == null || pads.length == 0) {
-            throw new IllegalStateException("Failed to get the pads in switch " + name);
-        }
-
-        return pads;
-    }
-
-    /**
-     * Controls the switch to select input/output nodes (pads).
-     *
-     * @param name The name of switch node
-     * @param pad  The name of the chosen pad to be activated
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to select the switch pad
-     */
-    public void selectSwitchPad(@NonNull String name, @NonNull String pad) {
-        checkPipelineHandle();
-
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given name is invalid");
-        }
-
-        if (pad == null || pad.isEmpty()) {
-            throw new IllegalArgumentException("Given pad is invalid");
-        }
-
-        if (!nativeSelectSwitchPad(mHandle, name, pad)) {
-            throw new IllegalStateException("Failed to select the pad " + pad);
-        }
-    }
-
-    /**
-     * Controls the valve.
-     * Set the flag true to open (let the flow pass), false to close (drop & stop the flow).
-     *
-     * @param name The name of valve node
-     * @param open The flag to control the flow
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to change the valve state
-     */
-    public void controlValve(@NonNull String name, boolean open) {
-        checkPipelineHandle();
-
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given name is invalid");
-        }
-
-        if (!nativeControlValve(mHandle, name, open)) {
-            throw new IllegalStateException("Failed to change the valve " + name);
-        }
-    }
-
-    /**
-     * Registers new data callback to sink node.
-     * The callback can be added in duplicate if an application tries to register multiple callbacks with same name.
-     *
-     * @param name     The name of sink node
-     * @param callback The callback for new data
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to register the callback to sink node in the pipeline
-     */
-    public void registerSinkCallback(@NonNull String name, @NonNull NewDataCallback callback) {
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given name is invalid");
-        }
-
-        if (callback == null) {
-            throw new IllegalArgumentException("Given callback is null");
-        }
-
-        synchronized(this) {
-            ArrayList<NewDataCallback> cbList = mSinkCallbacks.get(name);
-
-            if (cbList != null) {
-                /* check the list already includes same callback */
-                if (!cbList.contains(callback)) {
-                    cbList.add(callback);
-                }
-            } else {
-                if (nativeAddSinkCallback(mHandle, name)) {
-                    cbList = new ArrayList<>();
-                    cbList.add(callback);
-                    mSinkCallbacks.put(name, cbList);
-                } else {
-                    throw new IllegalStateException("Failed to register sink callback to " + name);
-                }
-            }
-        }
-    }
-
-    /**
-     * Unregisters data callback from sink node.
-     *
-     * @param name     The name of sink node
-     * @param callback The callback object to be unregistered
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to unregister the callback from sink node
-     */
-    public void unregisterSinkCallback(@NonNull String name, @NonNull NewDataCallback callback) {
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given name is invalid");
-        }
-
-        if (callback == null) {
-            throw new IllegalArgumentException("Given callback is null");
-        }
-
-        synchronized(this) {
-            ArrayList<NewDataCallback> cbList = mSinkCallbacks.get(name);
-
-            if (cbList == null || !cbList.contains(callback)) {
-                throw new IllegalStateException("Failed to unregister sink callback from " + name);
-            }
-
-            cbList.remove(callback);
-            if (cbList.isEmpty()) {
-                /* remove callback */
-                mSinkCallbacks.remove(name);
-                nativeRemoveSinkCallback(mHandle, name);
-            }
-        }
-    }
-
-    /**
-     * Sets a surface to video sink element.
-     * If {@code holder} is null, this will stop using the old surface.
-     *
-     * @param name   The name of video sink element
-     * @param holder The surface holder instance
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if failed to set the surface to video sink
-     */
-    public void setSurface(@NonNull String name, @Nullable SurfaceHolder holder) {
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given name is invalid");
-        }
-
-        if (holder == null) {
-            nativeFinalizeSurface(mHandle, name);
-        } else {
-            Surface surface = holder.getSurface();
-
-            if (surface == null || !surface.isValid()) {
-                throw new IllegalArgumentException("The surface is not available");
-            }
-
-            if (!nativeInitializeSurface(mHandle, name, surface)) {
-                throw new IllegalStateException("Failed to set the surface to " + name);
-            }
-        }
-    }
-
-    /**
-     * Internal method called from native when a new data is available.
-     */
-    private void newDataReceived(String name, TensorsData data) {
-        synchronized(this) {
-            ArrayList<NewDataCallback> cbList = mSinkCallbacks.get(name);
-
-            if (cbList != null) {
-                for (int i = 0; i < cbList.size(); i++) {
-                    cbList.get(i).onNewDataReceived(data);
-                }
-            }
-        }
-    }
-
-    /**
-     * Internal method called from native when the state of pipeline is changed.
-     */
-    private void stateChanged(int value) {
-        synchronized(this) {
-            if (mStateCallback != null) {
-                mStateCallback.onStateChanged(convertPipelineState(value));
-            }
-        }
-    }
-
-    /**
-     * Internal method to get the pipeline state from int value.
-     */
-    private State convertPipelineState(int value) {
-        State state = State.UNKNOWN;
-
-        switch (value) {
-            case 1:
-                state = State.NULL;
-                break;
-            case 2:
-                state = State.READY;
-                break;
-            case 3:
-                state = State.PAUSED;
-                break;
-            case 4:
-                state = State.PLAYING;
-                break;
-            default:
-                /* invalid or unknown state */
-                break;
-        }
-
-        return state;
-    }
-
-    /**
-     * Internal method to check native handle.
-     *
-     * @throws IllegalStateException if the pipeline is not constructed
-     */
-    private void checkPipelineHandle() {
-        if (mHandle == 0) {
-            throw new IllegalStateException("The pipeline is not constructed");
-        }
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    @Override
-    public void close() {
-        synchronized(this) {
-            mSinkCallbacks.clear();
-            mStateCallback = null;
-        }
-
-        if (mHandle != 0) {
-            nativeDestroy(mHandle);
-            mHandle = 0;
-        }
-    }
-}
diff --git a/api/android/api/src/main/java/org/nnsuite/nnstreamer/SingleShot.java b/api/android/api/src/main/java/org/nnsuite/nnstreamer/SingleShot.java
deleted file mode 100644 (file)
index fbcc0b0..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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.
- */
-
-package org.nnsuite.nnstreamer;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.io.File;
-
-/**
- * Provides interfaces to invoke a neural network model with a single instance of input data.<br>
- * This function is a syntactic sugar of NNStreamer Pipeline API with simplified features;
- * thus, users are supposed to use NNStreamer Pipeline API directly if they want more advanced features.<br>
- * The user is expected to preprocess the input data for the given neural network model.<br>
- * <br>
- * {@link SingleShot} allows the following operations with NNStreamer:<br>
- * - Open a machine learning model.<br>
- * - Interfaces to enter a single instance of input data to the opened model.<br>
- * - Utility functions to get the information of opened model.<br>
- */
-public final class SingleShot implements AutoCloseable {
-    private long mHandle = 0;
-
-    private native long nativeOpen(String[] models, TensorsInfo inputInfo, TensorsInfo outputInfo, int fw, String custom);
-    private native void nativeClose(long handle);
-    private native TensorsData nativeInvoke(long handle, TensorsData inputData);
-    private native TensorsInfo nativeGetInputInfo(long handle);
-    private native TensorsInfo nativeGetOutputInfo(long handle);
-    private native boolean nativeSetProperty(long handle, String name, String value);
-    private native String nativeGetProperty(long handle, String name);
-    private native boolean nativeSetInputInfo(long handle, TensorsInfo inputInfo);
-    private native boolean nativeSetTimeout(long handle, int timeout);
-
-    /**
-     * Creates a new {@link SingleShot} instance with the given model for TensorFlow Lite.
-     * If the model has flexible data dimensions, the pipeline will not be constructed and this will make an exception.
-     *
-     * @param model The path to the neural network model file
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if this failed to construct the pipeline
-     */
-    public SingleShot(@NonNull File model) {
-        this(new File[]{model}, null, null, NNStreamer.NNFWType.TENSORFLOW_LITE, null);
-    }
-
-    /**
-     * Creates a new {@link SingleShot} instance with the given model.
-     * If the model has flexible data dimensions, the pipeline will not be constructed and this will make an exception.
-     *
-     * @param model The {@link File} object to the neural network model file
-     * @param fw    The neural network framework
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if this failed to construct the pipeline
-     *
-     * @see NNStreamer#isAvailable(NNStreamer.NNFWType)
-     */
-    public SingleShot(@NonNull File model, NNStreamer.NNFWType fw) {
-        this(new File[]{model}, null, null, fw, null);
-    }
-
-    /**
-     * Creates a new {@link SingleShot} instance with the given model and custom option.
-     * If the model has flexible data dimensions, the pipeline will not be constructed and this will make an exception.
-     *
-     * @param model  The {@link File} object to the neural network model file
-     * @param fw     The neural network framework
-     * @param custom The custom option string to open the neural network
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if this failed to construct the pipeline
-     *
-     * @see NNStreamer#isAvailable(NNStreamer.NNFWType)
-     */
-    public SingleShot(@NonNull File model, NNStreamer.NNFWType fw, @Nullable String custom) {
-        this(new File[]{model}, null, null, fw, custom);
-    }
-
-    /**
-     * Creates a new {@link SingleShot} instance with the given model for TensorFlow Lite.
-     * The input and output tensors information are required if the given model has flexible data dimensions,
-     * where the information MUST be given before executing the model.
-     * However, once it's given, the dimension cannot be changed for the given model handle.
-     * You may set null if it's not required.
-     *
-     * @param model         The {@link File} object to the neural network model file
-     * @param inputInfo     The input tensors information
-     * @param outputInfo    The output tensors information
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException    if this failed to construct the pipeline
-     */
-    public SingleShot(@NonNull File model, @Nullable TensorsInfo inputInfo, @Nullable TensorsInfo outputInfo) {
-        this(new File[]{model}, inputInfo, outputInfo, NNStreamer.NNFWType.TENSORFLOW_LITE, null);
-    }
-
-    /**
-     * Creates a new {@link SingleShot} instance with the given files and custom option.
-     *
-     * Unlike other constructors, this handles multiple files and custom option string
-     * when the neural network requires various options and model files.
-     *
-     * @param models        The array of {@link File} objects to the neural network model files
-     * @param inputInfo     The input tensors information
-     * @param outputInfo    The output tensors information
-     * @param fw            The neural network framework
-     * @param custom        The custom option string to open the neural network
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException    if this failed to construct the pipeline
-     *
-     * @see NNStreamer#isAvailable(NNStreamer.NNFWType)
-     */
-    public SingleShot(@NonNull File[] models, @Nullable TensorsInfo inputInfo, @Nullable TensorsInfo outputInfo,
-                      NNStreamer.NNFWType fw, @Nullable String custom) {
-        this(new Options(fw, models, inputInfo, outputInfo, custom));
-    }
-
-    /**
-     * Creates a new {@link SingleShot} instance with the given {@link Options}.
-     *
-     * @param options   The {@link Options} object configuring the instance
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException    if this failed to construct the pipeline
-     */
-    public SingleShot(@NonNull Options options) {
-        File[] models = options.getModels();
-        NNStreamer.NNFWType fw = options.getNNFWType();
-        TensorsInfo inputInfo = options.getInputInfo();
-        TensorsInfo outputInfo = options.getOutputInfo();
-        String custom = options.getCustom();
-
-        String[] path = new String[models.length];
-        int index = 0;
-
-        for (File model : models) {
-            path[index++] = model.getAbsolutePath();
-        }
-
-        mHandle = nativeOpen(path, inputInfo, outputInfo, fw.ordinal(), custom);
-        if (mHandle == 0) {
-            throw new IllegalStateException("Failed to construct the SingleShot instance");
-        }
-    }
-
-    /**
-     * Invokes the model with the given input data.
-     *
-     * Even if the model has flexible input data dimensions,
-     * input data frames of an instance of a model should share the same dimension.
-     * To change the input information, you should call {@link #setInputInfo(TensorsInfo)} before calling invoke method.
-     *
-     * Note that this will wait for the result until the invoke process is done.
-     * If an application wants to change the time to wait for an output,
-     * set the timeout using {@link #setTimeout(int)}.
-     *
-     * @param in The input data to be inferred (a single frame, tensor/tensors)
-     *
-     * @return The output data (a single frame, tensor/tensors)
-     *
-     * @throws IllegalStateException if this failed to invoke the model
-     * @throws IllegalArgumentException if given param is null
-     */
-    public TensorsData invoke(@NonNull TensorsData in) {
-        checkPipelineHandle();
-
-        if (in == null) {
-            throw new IllegalArgumentException("Given input data is null");
-        }
-
-        TensorsData out = nativeInvoke(mHandle, in);
-        if (out == null) {
-            throw new IllegalStateException("Failed to invoke the model");
-        }
-
-        return out;
-    }
-
-    /**
-     * Gets the information (tensor dimension, type, name and so on) of required input data for the given model.
-     *
-     * @return The tensors information
-     *
-     * @throws IllegalStateException if this failed to get the input information
-     */
-    public TensorsInfo getInputInfo() {
-        checkPipelineHandle();
-
-        TensorsInfo info = nativeGetInputInfo(mHandle);
-        if (info == null) {
-            throw new IllegalStateException("Failed to get the input information");
-        }
-
-        return info;
-    }
-
-    /**
-     * Gets the information (tensor dimension, type, name and so on) of output data for the given model.
-     *
-     * @return The tensors information
-     *
-     * @throws IllegalStateException if this failed to get the output information
-     */
-    public TensorsInfo getOutputInfo() {
-        checkPipelineHandle();
-
-        TensorsInfo info = nativeGetOutputInfo(mHandle);
-        if (info == null) {
-            throw new IllegalStateException("Failed to get the output information");
-        }
-
-        return info;
-    }
-
-    /**
-     * Sets the property value for the given model.
-     * Note that a model/framework may not support to change the property after opening the model.
-     *
-     * @param name  The property name
-     * @param value The property value
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     */
-    public void setValue(@NonNull String name, @NonNull String value) {
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given property name is invalid");
-        }
-
-        if (value == null) {
-            throw new IllegalArgumentException("Given property value is invalid");
-        }
-
-        if (!nativeSetProperty(mHandle, name, value)) {
-            throw new IllegalArgumentException("Failed to set the property");
-        }
-    }
-
-    /**
-     * Gets the property value for the given model.
-     *
-     * @param name The property name
-     *
-     * @return The property value
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     */
-    public String getValue(@NonNull String name) {
-        if (name == null || name.isEmpty()) {
-            throw new IllegalArgumentException("Given property name is invalid");
-        }
-
-        String value = nativeGetProperty(mHandle, name);
-
-        if (value == null) {
-            throw new IllegalArgumentException("Failed to get the property");
-        }
-
-        return value;
-    }
-
-    /**
-     * Sets the maximum amount of time to wait for an output, in milliseconds.
-     *
-     * @param timeout The time to wait for an output
-     *
-     * @throws IllegalArgumentException if given param is invalid
-     * @throws IllegalStateException if this failed to set the timeout
-     */
-    public void setTimeout(int timeout) {
-        checkPipelineHandle();
-
-        if (timeout < 0) {
-            throw new IllegalArgumentException("Given timeout is invalid");
-        }
-
-        if (!nativeSetTimeout(mHandle, timeout)) {
-            throw new IllegalStateException("Failed to set the timeout");
-        }
-    }
-
-    /**
-     * Sets the information (tensor dimension, type, name and so on) of input data for the given model.
-     * Updates the output information for the model internally.
-     *
-     * Note that a model/framework may not support changing the information.
-     *
-     * @param in The input tensors information
-     *
-     * @throws IllegalStateException if this failed to set the input information
-     * @throws IllegalArgumentException if given param is null
-     */
-    public void setInputInfo(@NonNull TensorsInfo in) {
-        checkPipelineHandle();
-
-        if (in == null) {
-            throw new IllegalArgumentException("Given input info is null");
-        }
-
-        if (!nativeSetInputInfo(mHandle, in)) {
-            throw new IllegalStateException("Failed to set input tensor info");
-        }
-    }
-
-    /**
-     * Internal method to check native handle.
-     *
-     * @throws IllegalStateException if the pipeline is not constructed
-     */
-    private void checkPipelineHandle() {
-        if (mHandle == 0) {
-            throw new IllegalStateException("The pipeline is not constructed");
-        }
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    @Override
-    public void close() {
-        if (mHandle != 0) {
-            nativeClose(mHandle);
-            mHandle = 0;
-        }
-    }
-
-    /**
-     * Provides interfaces to configure SingleShot instance.
-     */
-    public static class Options {
-        private NNStreamer.NNFWType fw = NNStreamer.NNFWType.UNKNOWN;
-        private File[] models;
-        private TensorsInfo inputInfo;
-        private TensorsInfo outputInfo;
-        private String custom;
-
-        /**
-         * Creates a new {@link Options} instance with the given framework and file.
-         *
-         * @param type  The type of {@link NNStreamer.NNFWType}
-         * @param model The {@link File} object to the neural network model file
-         *
-         * @throws IllegalArgumentException if given model is invalid
-         * @throws IllegalStateException    if given framework is not available
-         */
-        public Options(NNStreamer.NNFWType type, File model) {
-            setNNFWType(type);
-            setModels(new File[]{model});
-        }
-
-        /**
-         * Creates a new {@link Options} instance with the given framework and file.
-         *
-         * @param type   The type of {@link NNStreamer.NNFWType}
-         * @param models The array of {@link File} objects to the neural network model files
-         *
-         * @throws IllegalArgumentException if given models is invalid
-         * @throws IllegalStateException    if given framework is not available
-         */
-        public Options(NNStreamer.NNFWType type, File[] models) {
-            setNNFWType(type);
-            setModels(models);
-        }
-
-        /**
-         * Creates a new {@link Options} instance with the given parameters.
-         *
-         * @param type              The type of {@link NNStreamer.NNFWType}
-         * @param models            The array of {@link File} objects to the neural network model files
-         * @param inputInfo         The input tensors information
-         * @param outputInfo        The output tensors information
-         * @param custom            The custom option string to open the neural network instance
-         *
-         * @throws IllegalArgumentException if given models is invalid
-         * @throws IllegalStateException    if given framework is not available
-         */
-        public Options(NNStreamer.NNFWType type, File[] models, TensorsInfo inputInfo, TensorsInfo outputInfo, String custom) {
-            setNNFWType(type);
-            setModels(models);
-            setInputInfo(inputInfo);
-            setOutputInfo(outputInfo);
-            setCustom(custom);
-        }
-
-        public NNStreamer.NNFWType getNNFWType() {
-            return fw;
-        }
-
-        public void setNNFWType(NNStreamer.NNFWType fw) {
-            if (!NNStreamer.isAvailable(fw)) {
-                throw new IllegalStateException("Given framework " + fw.name() + " is not available");
-            }
-            this.fw = fw;
-        }
-
-        public File[] getModels() {
-            return models;
-        }
-
-        public void setModels(File[] models) {
-            if (models == null) {
-                throw new IllegalArgumentException("Given model is invalid");
-            }
-
-            for (File model : models) {
-                if (model == null || !model.exists()) {
-                    throw new IllegalArgumentException("Given model is invalid");
-                }
-            }
-
-            this.models = models;
-        }
-
-        public TensorsInfo getInputInfo() {
-            return inputInfo;
-        }
-
-        public void setInputInfo(TensorsInfo inputInfo) {
-            this.inputInfo = inputInfo;
-        }
-
-        public TensorsInfo getOutputInfo() {
-            return outputInfo;
-        }
-
-        public void setOutputInfo(TensorsInfo outputInfo) {
-            this.outputInfo = outputInfo;
-        }
-
-        public String getCustom() {
-            return custom;
-        }
-
-        public void setCustom(String custom) {
-            this.custom = custom;
-        }
-    }
-}
diff --git a/api/android/api/src/main/java/org/nnsuite/nnstreamer/TensorsData.java b/api/android/api/src/main/java/org/nnsuite/nnstreamer/TensorsData.java
deleted file mode 100644 (file)
index 59caccf..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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.
- */
-
-package org.nnsuite.nnstreamer;
-
-import android.support.annotation.NonNull;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-
-/**
- * Provides interfaces to handle tensor data frame.
- */
-public final class TensorsData implements AutoCloseable {
-    private TensorsInfo mInfo = null;
-    private ArrayList<ByteBuffer> mDataList = new ArrayList<>();
-
-    /**
-     * Allocates a new direct byte buffer with the native byte order.
-     *
-     * @param size The byte size of the buffer
-     *
-     * @return The new byte buffer
-     *
-     * @throws IllegalArgumentException if given size is invalid
-     */
-    public static ByteBuffer allocateByteBuffer(int size) {
-        if (size <= 0) {
-            throw new IllegalArgumentException("Given size is invalid");
-        }
-
-        return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
-    }
-
-    /**
-     * Allocates a new {@link TensorsData} instance with the given tensors information.
-     *
-     * @param info The tensors information
-     *
-     * @return {@link TensorsData} instance
-     *
-     * @throws IllegalArgumentException if given info is invalid
-     */
-    public static TensorsData allocate(@NonNull TensorsInfo info) {
-        if (info == null || info.getTensorsCount() == 0) {
-            throw new IllegalArgumentException("Given info is invalid");
-        }
-
-        TensorsData data = new TensorsData(info);
-        int count = info.getTensorsCount();
-
-        for (int i = 0; i < count; i++) {
-            data.addTensorData(allocateByteBuffer(info.getTensorSize(i)));
-        }
-
-        return data;
-    }
-
-    /**
-     * Gets the tensors information.
-     *
-     * @return {@link TensorsInfo} instance cloned from current tensors information.
-     */
-    public TensorsInfo getTensorsInfo() {
-        return mInfo.clone();
-    }
-
-    /**
-     * Sets the tensors information.
-     *
-     * @param info The tensors information
-     *
-     * @throws IllegalArgumentException if given info is null
-     */
-    private void setTensorsInfo(@NonNull TensorsInfo info) {
-        if (info == null || info.getTensorsCount() == 0) {
-            throw new IllegalArgumentException("Given info is invalid");
-        }
-
-        mInfo = info.clone();
-    }
-
-    /**
-     * Gets the number of tensors in tensors data.
-     *
-     * @return The number of tensors
-     */
-    public int getTensorsCount() {
-        return mDataList.size();
-    }
-
-    /**
-     * Adds a new tensor data.
-     *
-     * @param data The tensor data to be added
-     *
-     * @throws IllegalArgumentException if given data is invalid
-     * @throws IndexOutOfBoundsException when the maximum number of tensors in the list
-     */
-    private void addTensorData(@NonNull ByteBuffer data) {
-        int index = getTensorsCount();
-
-        checkByteBuffer(index, data);
-        mDataList.add(data);
-    }
-
-    /**
-     * Gets a tensor data of given index.
-     *
-     * @param index The index of the tensor in the list
-     *
-     * @return The tensor data
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     */
-    public ByteBuffer getTensorData(int index) {
-        checkIndexBounds(index);
-        return mDataList.get(index);
-    }
-
-    /**
-     * Sets a tensor data.
-     *
-     * @param index The index of the tensor in the list
-     * @param data  The tensor data
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     * @throws IllegalArgumentException if given data is invalid
-     */
-    public void setTensorData(int index, @NonNull ByteBuffer data) {
-        checkIndexBounds(index);
-        checkByteBuffer(index, data);
-
-        mDataList.set(index, data);
-    }
-
-    /**
-     * Internal method called from native to get the array of tensor data.
-     */
-    private Object[] getDataArray() {
-        return mDataList.toArray();
-    }
-
-    /**
-     * Internal method to check the index.
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     */
-    private void checkIndexBounds(int index) {
-        if (index < 0 || index >= getTensorsCount()) {
-            throw new IndexOutOfBoundsException("Invalid index [" + index + "] of the tensors");
-        }
-    }
-
-    /**
-     * Internal method to check byte buffer.
-     *
-     * @throws IllegalArgumentException if given data is invalid
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     */
-    private void checkByteBuffer(int index, ByteBuffer data) {
-        if (data == null) {
-            throw new IllegalArgumentException("Given data is null");
-        }
-
-        if (!data.isDirect()) {
-            throw new IllegalArgumentException("Given data is not a direct buffer");
-        }
-
-        if (data.order() != ByteOrder.nativeOrder()) {
-            /* Default byte order of ByteBuffer in java is big-endian, it should be a little-endian. */
-            throw new IllegalArgumentException("Given data has invalid byte order");
-        }
-
-        if (index >= NNStreamer.TENSOR_SIZE_LIMIT) {
-            throw new IndexOutOfBoundsException("Max size of the tensors is " + NNStreamer.TENSOR_SIZE_LIMIT);
-        }
-
-        /* compare to tensors info */
-        if (mInfo != null) {
-            int count = mInfo.getTensorsCount();
-
-            if (index >= count) {
-                throw new IndexOutOfBoundsException("Current information has " + count + " tensors");
-            }
-
-            int size = mInfo.getTensorSize(index);
-
-            if (data.capacity() != size) {
-                throw new IllegalArgumentException("Invalid buffer size, required size is " + size);
-            }
-        }
-    }
-
-    @Override
-    public void close() {
-        mDataList.clear();
-        mInfo = null;
-    }
-
-    /**
-     * Private constructor to prevent the instantiation.
-     */
-    private TensorsData(TensorsInfo info) {
-        setTensorsInfo(info);
-    }
-}
diff --git a/api/android/api/src/main/java/org/nnsuite/nnstreamer/TensorsInfo.java b/api/android/api/src/main/java/org/nnsuite/nnstreamer/TensorsInfo.java
deleted file mode 100644 (file)
index 5dfd83e..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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.
- */
-
-package org.nnsuite.nnstreamer;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.util.ArrayList;
-
-/**
- * Provides interfaces to handle tensors information.
- *
- * @see NNStreamer#TENSOR_RANK_LIMIT
- * @see NNStreamer#TENSOR_SIZE_LIMIT
- * @see NNStreamer.TensorType
- */
-public final class TensorsInfo implements AutoCloseable, Cloneable {
-    private ArrayList<TensorInfo> mInfoList = new ArrayList<>();
-
-    /**
-     * Allocates a new {@link TensorsData} instance with the tensors information.
-     *
-     * @return {@link TensorsData} instance
-     *
-     * @throws IllegalStateException if tensors info is empty
-     */
-    public TensorsData allocate() {
-        if (getTensorsCount() == 0) {
-            throw new IllegalStateException("Empty tensor info");
-        }
-
-        return TensorsData.allocate(this);
-    }
-
-    /**
-     * Creates a new {@link TensorsInfo} instance cloned from the current tensors information.
-     *
-     * @return {@link TensorsInfo} instance
-     */
-    @Override
-    public TensorsInfo clone() {
-        TensorsInfo cloned = new TensorsInfo();
-
-        for (TensorInfo info : mInfoList) {
-            cloned.addTensorInfo(info.getName(), info.getType(), info.getDimension());
-        }
-
-        return cloned;
-    }
-
-    /**
-     * Gets the number of tensors.
-     * The maximum number of tensors is {@link NNStreamer#TENSOR_SIZE_LIMIT}.
-     *
-     * @return The number of tensors
-     */
-    public int getTensorsCount() {
-        return mInfoList.size();
-    }
-
-    /**
-     * Adds a new tensor information.
-     *
-     * @param type      The tensor data type
-     * @param dimension The tensor dimension
-     *
-     * @throws IndexOutOfBoundsException when the maximum number of tensors in the list
-     * @throws IllegalArgumentException if given param is null or invalid
-     */
-    public void addTensorInfo(NNStreamer.TensorType type, @NonNull int[] dimension) {
-        addTensorInfo(null, type, dimension);
-    }
-
-    /**
-     * Adds a new tensor information.
-     *
-     * @param name      The tensor name
-     * @param type      The tensor data type
-     * @param dimension The tensor dimension
-     *
-     * @throws IndexOutOfBoundsException when the maximum number of tensors in the list
-     * @throws IllegalArgumentException if given param is null or invalid
-     */
-    public void addTensorInfo(@Nullable String name, NNStreamer.TensorType type, @NonNull int[] dimension) {
-        int index = getTensorsCount();
-
-        if (index >= NNStreamer.TENSOR_SIZE_LIMIT) {
-            throw new IndexOutOfBoundsException("Max number of the tensors is " + NNStreamer.TENSOR_SIZE_LIMIT);
-        }
-
-        mInfoList.add(new TensorInfo(name, type, dimension));
-    }
-
-    /**
-     * Sets the tensor name.
-     *
-     * @param index The index of the tensor information in the list
-     * @param name  The tensor name
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     */
-    public void setTensorName(int index, String name) {
-        checkIndexBounds(index);
-        mInfoList.get(index).setName(name);
-    }
-
-    /**
-     * Gets the tensor name of given index.
-     *
-     * @param index The index of the tensor information in the list
-     *
-     * @return The tensor name
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     */
-    public String getTensorName(int index) {
-        checkIndexBounds(index);
-        return mInfoList.get(index).getName();
-    }
-
-    /**
-     * Sets the tensor data type.
-     *
-     * @param index The index of the tensor information in the list
-     * @param type  The tensor type
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     * @throws IllegalArgumentException if the given type is unknown or unsupported type
-     */
-    public void setTensorType(int index, NNStreamer.TensorType type) {
-        checkIndexBounds(index);
-        mInfoList.get(index).setType(type);
-    }
-
-    /**
-     * Gets the tensor data type of given index.
-     *
-     * @param index The index of the tensor information in the list
-     *
-     * @return The tensor data type
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     */
-    public NNStreamer.TensorType getTensorType(int index) {
-        checkIndexBounds(index);
-        return mInfoList.get(index).getType();
-    }
-
-    /**
-     * Sets the tensor dimension
-     *
-     * @param index     The index of the tensor information in the list
-     * @param dimension The tensor dimension
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     * @throws IllegalArgumentException if the given dimension is null or invalid
-     */
-    public void setTensorDimension(int index, @NonNull int[] dimension) {
-        checkIndexBounds(index);
-        mInfoList.get(index).setDimension(dimension);
-    }
-
-    /**
-     * Gets the tensor dimension of given index.
-     *
-     * @param index The index of the tensor information in the list
-     *
-     * @return The tensor dimension
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     */
-    public int[] getTensorDimension(int index) {
-        checkIndexBounds(index);
-        return mInfoList.get(index).getDimension();
-    }
-
-    /**
-     * Calculates the byte size of tensor data.
-     *
-     * @param index The index of the tensor information in the list
-     *
-     * @return The byte size of tensor
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     * @throws IllegalStateException if data type or dimension is invalid
-     */
-    public int getTensorSize(int index) {
-        checkIndexBounds(index);
-
-        int size = mInfoList.get(index).getSize();
-        if (size <= 0) {
-            throw new IllegalStateException("Unknown data type or invalid dimension");
-        }
-
-        return size;
-    }
-
-    /**
-     * Internal method called from native to add new info.
-     */
-    private void appendInfo(String name, int type, int[] dimension) {
-        addTensorInfo(name, TensorInfo.convertType(type), dimension);
-    }
-
-    /**
-     * Internal method called from native to get the array of tensor info.
-     */
-    private Object[] getInfoArray() {
-        return mInfoList.toArray();
-    }
-
-    /**
-     * Internal method to check the index.
-     *
-     * @throws IndexOutOfBoundsException if the given index is invalid
-     */
-    private void checkIndexBounds(int index) {
-        if (index < 0 || index >= getTensorsCount()) {
-            throw new IndexOutOfBoundsException("Invalid index [" + index + "] of the tensors");
-        }
-    }
-
-    @Override
-    public void close() {
-        mInfoList.clear();
-    }
-
-    /**
-     * Internal class for tensor information.
-     */
-    private static class TensorInfo {
-        private String name = null;
-        private int type = NNStreamer.TensorType.UNKNOWN.ordinal();
-        private int[] dimension = new int[NNStreamer.TENSOR_RANK_LIMIT];
-
-        public TensorInfo(@Nullable String name, NNStreamer.TensorType type, @NonNull int[] dimension) {
-            setName(name);
-            setType(type);
-            setDimension(dimension);
-        }
-
-        public void setName(@Nullable String name) {
-            this.name = name;
-        }
-
-        public String getName() {
-            return this.name;
-        }
-
-        public void setType(NNStreamer.TensorType type) {
-            if (type == NNStreamer.TensorType.UNKNOWN) {
-                throw new IllegalArgumentException("Given tensor type is unknown or unsupported type");
-            }
-
-            this.type = type.ordinal();
-        }
-
-        public NNStreamer.TensorType getType() {
-            return convertType(this.type);
-        }
-
-        public void setDimension(@NonNull int[] dimension) {
-            if (dimension == null) {
-                throw new IllegalArgumentException("Given tensor dimension is null");
-            }
-
-            int rank = dimension.length;
-
-            if (rank > NNStreamer.TENSOR_RANK_LIMIT) {
-                throw new IllegalArgumentException("Max size of the tensor rank is " + NNStreamer.TENSOR_RANK_LIMIT);
-            }
-
-            for (int dim : dimension) {
-                if (dim <= 0) {
-                    throw new IllegalArgumentException("The dimension should be a positive value");
-                }
-            }
-
-            System.arraycopy(dimension, 0, this.dimension, 0, rank);
-
-            /* fill default value */
-            for (int i = rank; i < NNStreamer.TENSOR_RANK_LIMIT; i++) {
-                this.dimension[i] = 1;
-            }
-        }
-
-        public int[] getDimension() {
-            return this.dimension;
-        }
-
-        public int getSize() {
-            int size;
-
-            switch (convertType(this.type)) {
-                case INT32:
-                case UINT32:
-                case FLOAT32:
-                    size = 4;
-                    break;
-                case INT16:
-                case UINT16:
-                    size = 2;
-                    break;
-                case INT8:
-                case UINT8:
-                    size = 1;
-                    break;
-                case INT64:
-                case UINT64:
-                case FLOAT64:
-                    size = 8;
-                    break;
-                default:
-                    /* unknown type */
-                    return 0;
-            }
-
-            for (int i = 0; i < NNStreamer.TENSOR_RANK_LIMIT; i++) {
-                size *= this.dimension[i];
-            }
-
-            return size;
-        }
-
-        /**
-         * Gets the tensor type from int value.
-         */
-        public static NNStreamer.TensorType convertType(int value) {
-            NNStreamer.TensorType type = NNStreamer.TensorType.UNKNOWN;
-
-            switch (value) {
-                case 0:
-                    type = NNStreamer.TensorType.INT32;
-                    break;
-                case 1:
-                    type = NNStreamer.TensorType.UINT32;
-                    break;
-                case 2:
-                    type = NNStreamer.TensorType.INT16;
-                    break;
-                case 3:
-                    type = NNStreamer.TensorType.UINT16;
-                    break;
-                case 4:
-                    type = NNStreamer.TensorType.INT8;
-                    break;
-                case 5:
-                    type = NNStreamer.TensorType.UINT8;
-                    break;
-                case 6:
-                    type = NNStreamer.TensorType.FLOAT64;
-                    break;
-                case 7:
-                    type = NNStreamer.TensorType.FLOAT32;
-                    break;
-                case 8:
-                    type = NNStreamer.TensorType.INT64;
-                    break;
-                case 9:
-                    type = NNStreamer.TensorType.UINT64;
-                    break;
-                default:
-                    /* unknown type */
-                    break;
-            }
-
-            return type;
-        }
-    }
-}
diff --git a/api/android/api/src/main/jni/Android-dec-flatbuf.mk b/api/android/api/src/main/jni/Android-dec-flatbuf.mk
deleted file mode 100644 (file)
index ac5e37d..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#------------------------------------------------------
-# flatbuffers
-#
-# This mk file defines the flatbuffers-module with the prebuilt static library.
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
-endif
-
-include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
-
-FLATBUF_VER := @FLATBUF_VER@
-ifeq ($(FLATBUF_VER),@FLATBUF_VER@)
-$(error 'FLATBUF_VER' is not properly set)
-endif
-
-ifeq ($(shell which flatc),)
-$(error No 'flatc' in your PATH, install flatbuffers-compiler from ppa:nnstreamer/ppa)
-else
-SYS_FLATC_VER := $(word 3, $(shell flatc --version))
-endif
-
-ifneq ($(SYS_FLATC_VER), $(FLATBUF_VER))
-$(error Found 'flatc' v$(SYS_FLATC_VER), but required v$(FLATBUF_VER))
-endif
-
-FLATBUF_DIR := $(LOCAL_PATH)/flatbuffers
-FLATBUF_INCLUDES := $(FLATBUF_DIR)/include
-GEN_FLATBUF_HEADER := $(shell flatc --cpp -o $(LOCAL_PATH) $(NNSTREAMER_ROOT)/ext/nnstreamer/include/nnstreamer.fbs )
-FLATBUF_HEADER_GEN := $(wildcard $(LOCAL_PATH)/nnstreamer_generated.h)
-ifeq ($(FLATBUF_HEADER_GEN), '')
-$(error Failed to generate the header file, '$(LOCAL_PATH)/nnstreamer_generated.h')
-endif
-
-FLATBUF_LIB_PATH := $(FLATBUF_DIR)/lib/$(TARGET_ARCH_ABI)
-ifeq ($(wildcard $(FLATBUF_LIB_PATH)), )
-$(error The given ABI is not supported by the flatbuffers-module: $(TARGET_ARCH_ABI))
-endif
-
-#------------------------------------------------------
-# libflatbuffers.a (prebuilt static library)
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := flatbuffers-lib
-LOCAL_SRC_FILES := $(FLATBUF_LIB_PATH)/libflatbuffers.a
-
-include $(PREBUILT_STATIC_LIBRARY)
-
-#------------------------------------------------------
-# tensor-decoder sub-plugin for flatbuffers
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := flatbuffers-subplugin
-LOCAL_SRC_FILES := $(NNSTREAMER_DECODER_FLATBUF_SRCS)
-LOCAL_C_INCLUDES := $(LOCAL_PATH) $(FLATBUF_INCLUDES) $(NNSTREAMER_INCLUDES) $(GST_HEADERS_COMMON)
-LOCAL_STATIC_LIBRARIES := flatbuffers-lib
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/api/android/api/src/main/jni/Android-gst-plugins.mk b/api/android/api/src/main/jni/Android-gst-plugins.mk
deleted file mode 100644 (file)
index e778193..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#------------------------------------------------------
-# Define GStreamer plugins and extra dependencies
-#------------------------------------------------------
-
-ifndef NNSTREAMER_API_OPTION
-$(error NNSTREAMER_API_OPTION is not defined!)
-endif
-
-ifndef GSTREAMER_NDK_BUILD_PATH
-GSTREAMER_NDK_BUILD_PATH := $(GSTREAMER_ROOT)/share/gst-android/ndk-build
-endif
-
-include $(GSTREAMER_NDK_BUILD_PATH)/plugins.mk
-
-ifeq ($(NNSTREAMER_API_OPTION),all)
-GST_REQUIRED_PLUGINS := $(GSTREAMER_PLUGINS_CORE) \
-    $(GSTREAMER_PLUGINS_CODECS) \
-    $(GSTREAMER_PLUGINS_ENCODING) \
-    $(GSTREAMER_PLUGINS_NET) \
-    $(GSTREAMER_PLUGINS_PLAYBACK) \
-    $(GSTREAMER_PLUGINS_VIS) \
-    $(GSTREAMER_PLUGINS_SYS) \
-    $(GSTREAMER_PLUGINS_EFFECTS) \
-    $(GSTREAMER_PLUGINS_CAPTURE) \
-    $(GSTREAMER_PLUGINS_CODECS_GPL) \
-    $(GSTREAMER_PLUGINS_CODECS_RESTRICTED) \
-    $(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 :=
-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 :=
-else ifeq ($(NNSTREAMER_API_OPTION),single)
-GST_REQUIRED_PLUGINS :=
-GST_REQUIRED_DEPS :=
-GST_REQUIRED_LIBS :=
-else
-$(error Unknown build option: $(NNSTREAMER_API_OPTION))
-endif
-
diff --git a/api/android/api/src/main/jni/Android-nnfw-prebuilt.mk b/api/android/api/src/main/jni/Android-nnfw-prebuilt.mk
deleted file mode 100644 (file)
index f8b7fa4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#------------------------------------------------------
-# NNFW (On-device neural network inference framework, which is developed by Samsung Research.)
-# https://github.com/Samsung/ONE
-#
-# This mk file defines prebuilt libraries for nnfw module.
-# (nnfw core libraries, arm64-v8a only)
-# You can download specific version of nnfw libraries from https://github.com/Samsung/ONE/releases.
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef NNFW_LIB_PATH
-$(error NNFW_LIB_PATH is not defined!)
-endif
-
-NNFW_PREBUILT_LIBS :=
-
-#------------------------------------------------------
-# nnfw prebuilt shared libraries
-#------------------------------------------------------
-include $(CLEAR_VARS)
-LOCAL_MODULE := nnfw-libnnfw-dev
-LOCAL_SRC_FILES := $(NNFW_LIB_PATH)/libnnfw-dev.so
-include $(PREBUILT_SHARED_LIBRARY)
-NNFW_PREBUILT_LIBS += nnfw-libnnfw-dev
diff --git a/api/android/api/src/main/jni/Android-nnfw.mk b/api/android/api/src/main/jni/Android-nnfw.mk
deleted file mode 100644 (file)
index 8f82a37..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#------------------------------------------------------
-# NNFW (On-device neural network inference framework, which is developed by Samsung Research.)
-# https://github.com/Samsung/ONE
-#
-# This mk file defines nnfw module with prebuilt shared library.
-# (nnfw core libraries, arm64-v8a only)
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
-endif
-
-include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
-
-NNFW_DIR := $(LOCAL_PATH)/nnfw
-NNFW_INCLUDES := $(NNFW_DIR)/include $(NNFW_DIR)/include/nnfw
-
-ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
-NNFW_LIB_PATH := $(NNFW_DIR)/lib
-else
-$(error Target arch ABI not supported: $(TARGET_ARCH_ABI))
-endif
-
-#------------------------------------------------------
-# nnfw prebuilt shared libraries
-#------------------------------------------------------
-include $(LOCAL_PATH)/Android-nnfw-prebuilt.mk
-
-#------------------------------------------------------
-# tensor-filter sub-plugin for nnfw
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := nnfw-subplugin
-LOCAL_SRC_FILES := $(NNSTREAMER_FILTER_NNFW_SRCS)
-LOCAL_CFLAGS := -O3 -fPIC $(NNS_API_FLAGS)
-LOCAL_C_INCLUDES := $(NNFW_INCLUDES) $(NNSTREAMER_INCLUDES) $(GST_HEADERS_COMMON)
-LOCAL_SHARED_LIBRARIES := $(NNFW_PREBUILT_LIBS)
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/api/android/api/src/main/jni/Android-nnstreamer-prebuilt.mk b/api/android/api/src/main/jni/Android-nnstreamer-prebuilt.mk
deleted file mode 100644 (file)
index 565a4e1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#------------------------------------------------------
-# nnstreamer
-#
-# This mk file defines nnstreamer module with prebuilt shared libraries.
-# ABI: armeabi-v7a, arm64-v8a
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-NNSTREAMER_DIR := $(LOCAL_PATH)/nnstreamer
-
-NNSTREAMER_INCLUDES := $(NNSTREAMER_DIR)/include
-NNSTREAMER_LIB_PATH := $(NNSTREAMER_DIR)/lib/$(TARGET_ARCH_ABI)
-
-ENABLE_TF_LITE := false
-ENABLE_SNAP := false
-ENABLE_NNFW := false
-ENABLE_SNPE := false
-
-#------------------------------------------------------
-# define required libraries for nnstreamer
-#------------------------------------------------------
-NNSTREAMER_LIBS := nnstreamer-native gst-android cpp-shared
-
-#------------------------------------------------------
-# nnstreamer-native
-#------------------------------------------------------
-include $(CLEAR_VARS)
-LOCAL_MODULE := nnstreamer-native
-LOCAL_SRC_FILES := $(NNSTREAMER_LIB_PATH)/libnnstreamer-native.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-#------------------------------------------------------
-# gstreamer android
-#------------------------------------------------------
-include $(CLEAR_VARS)
-LOCAL_MODULE := gst-android
-LOCAL_SRC_FILES := $(NNSTREAMER_LIB_PATH)/libgstreamer_android.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-#------------------------------------------------------
-# c++ shared
-#------------------------------------------------------
-include $(CLEAR_VARS)
-LOCAL_MODULE := cpp-shared
-LOCAL_SRC_FILES := $(NNSTREAMER_LIB_PATH)/libc++_shared.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-#------------------------------------------------------
-# SNAP (arm64-v8a only)
-#------------------------------------------------------
-ifeq ($(ENABLE_SNAP),true)
-SNAP_LIB_PATH := $(NNSTREAMER_LIB_PATH)
-include $(LOCAL_PATH)/Android-snap-prebuilt.mk
-
-NNSTREAMER_LIBS += $(SNAP_PREBUILT_LIBS)
-endif
-
-#------------------------------------------------------
-# NNFW (arm64-v8a only)
-#------------------------------------------------------
-ifeq ($(ENABLE_NNFW),true)
-NNFW_LIB_PATH := $(NNSTREAMER_LIB_PATH)
-include $(LOCAL_PATH)/Android-nnfw-prebuilt.mk
-
-NNSTREAMER_LIBS += $(NNFW_PREBUILT_LIBS)
-endif
-
-#------------------------------------------------------
-# SNPE
-#------------------------------------------------------
-ifeq ($(ENABLE_SNPE),true)
-SNPE_LIB_PATH := $(NNSTREAMER_LIB_PATH)
-include $(LOCAL_PATH)/Android-snpe-prebuilt.mk
-
-NNSTREAMER_LIBS += $(SNPE_PREBUILT_LIBS)
-endif
-
-# Remove any duplicates.
-NNSTREAMER_LIBS := $(sort $(NNSTREAMER_LIBS))
diff --git a/api/android/api/src/main/jni/Android-nnstreamer.mk b/api/android/api/src/main/jni/Android-nnstreamer.mk
deleted file mode 100644 (file)
index c6ba17a..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#------------------------------------------------------
-# nnstreamer
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
-endif
-
-include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
-
-NNSTREAMER_SRC_FILES := \
-    $(NNSTREAMER_COMMON_SRCS)
-
-ifeq ($(NNSTREAMER_API_OPTION),single)
-# single-shot only
-NNSTREAMER_SRC_FILES += \
-    $(NNSTREAMER_SINGLE_SRCS)
-else
-# capi and nnstreamer plugins
-NNSTREAMER_SRC_FILES += \
-    $(NNSTREAMER_CAPI_SRCS) \
-    $(NNSTREAMER_PLUGINS_SRCS) \
-    $(NNSTREAMER_SOURCE_AMC_SRCS) \
-    $(NNSTREAMER_DECODER_BB_SRCS) \
-    $(NNSTREAMER_DECODER_DV_SRCS) \
-    $(NNSTREAMER_DECODER_IL_SRCS) \
-    $(NNSTREAMER_DECODER_PE_SRCS) \
-    $(NNSTREAMER_DECODER_IS_SRCS) \
-    $(NNSTREAMER_JOIN_SRCS)
-endif
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := nnstreamer
-LOCAL_SRC_FILES := $(sort $(NNSTREAMER_SRC_FILES))
-LOCAL_C_INCLUDES := $(NNS_API_INCLUDES)
-LOCAL_CFLAGS := -O3 -fPIC $(NNS_API_FLAGS)
-LOCAL_CXXFLAGS := -std=c++11 -O3 -fPIC -frtti -fexceptions $(NNS_API_FLAGS)
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/api/android/api/src/main/jni/Android-pytorch.mk b/api/android/api/src/main/jni/Android-pytorch.mk
deleted file mode 100644 (file)
index e8a3a74..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#------------------------------------------------------
-# PyTorch
-#
-# This mk file defines PyTorch module with prebuilt static library.
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
-endif
-
-include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
-
-# To support NNAPI, which is not available in the lastest stable release (1.7.1) of PyTorch,
-# This module use commit ID 5c3788d5d76f64f6708e0b79f40b1cf45276625a for PyTorch
-# (https://github.com/pytorch/pytorch @ 5c3788d5d76f64f6708e0b79f40b1cf45276625a)
-# After a release of PyTorch which includes NNAPI support, this will be updated.
-PYTORCH_VERSION := 1.8.0
-
-PYTORCH_FLAGS := \
-    -DPYTORCH_VERSION=$(PYTORCH_VERSION) \
-    -DPYTORCH_VER_ATLEAST_1_2_0=1
-
-PYTORCH_DIR := $(LOCAL_PATH)/pytorch
-PYTORCH_INCLUDES := $(PYTORCH_DIR)/include
-
-ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
-PYTORCH_LIB_PATH := $(PYTORCH_DIR)/lib/arm64
-else
-$(error Target arch ABI not supported: $(TARGET_ARCH_ABI))
-endif
-
-#------------------------------------------------------
-# pytorch (prebuilt static library)
-#------------------------------------------------------
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libc10
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libc10.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libclog
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libclog.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libcpuinfo
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libcpuinfo.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libeigen_blas
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libeigen_blas.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libnnpack
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libnnpack.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libpthreadpool
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libpthreadpool.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libpytorch_qnnpack
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libpytorch_qnnpack.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libXNNPACK
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libXNNPACK.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libtorch_cpu
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libtorch_cpu.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pytorch-libtorch
-LOCAL_SRC_FILES := $(PYTORCH_LIB_PATH)/libtorch.a
-include $(PREBUILT_STATIC_LIBRARY)
-
-#------------------------------------------------------
-# tensor-filter sub-plugin for pytorch
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := pytorch-subplugin
-LOCAL_SRC_FILES := $(NNSTREAMER_FILTER_PYTORCH_SRCS)
-LOCAL_CXXFLAGS := -std=c++14 -O3 -fPIC -frtti -fexceptions $(NNS_API_FLAGS) $(PYTORCH_FLAGS)
-LOCAL_C_INCLUDES := $(PYTORCH_INCLUDES) $(NNSTREAMER_INCLUDES) $(GST_HEADERS_COMMON)
-LOCAL_WHOLE_STATIC_LIBRARIES := pytorch-libeigen_blas pytorch-libnnpack pytorch-libpytorch_qnnpack pytorch-libXNNPACK pytorch-libtorch_cpu pytorch-libtorch pytorch-libc10 pytorch-libcpuinfo pytorch-libpthreadpool pytorch-libclog
-include $(BUILD_STATIC_LIBRARY)
diff --git a/api/android/api/src/main/jni/Android-snap-prebuilt.mk b/api/android/api/src/main/jni/Android-snap-prebuilt.mk
deleted file mode 100644 (file)
index 897e18c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#------------------------------------------------------
-# SNAP (Samsung Neural Acceleration Platform)
-#
-# This mk file defines prebuilt libraries for snap module.
-# (snap-sdk, arm64-v8a only)
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef SNAP_LIB_PATH
-$(error SNAP_LIB_PATH is not defined!)
-endif
-
-SNAP_PREBUILT_LIBS :=
-
-#------------------------------------------------------
-# snap-sdk (prebuilt shared library)
-#------------------------------------------------------
-include $(CLEAR_VARS)
-LOCAL_MODULE := snap-sdk
-LOCAL_SRC_FILES := $(SNAP_LIB_PATH)/libsnap_vndk.so
-include $(PREBUILT_SHARED_LIBRARY)
-SNAP_PREBUILT_LIBS += snap-sdk
diff --git a/api/android/api/src/main/jni/Android-snap.mk b/api/android/api/src/main/jni/Android-snap.mk
deleted file mode 100644 (file)
index 6c30757..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#------------------------------------------------------
-# SNAP (Samsung Neural Acceleration Platform)
-#
-# This mk file defines snap module with prebuilt shared library.
-# (snap-sdk, arm64-v8a only)
-# See Samsung Neural SDK (https://developer.samsung.com/neural) for the details.
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
-endif
-
-include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
-
-SNAP_DIR := $(LOCAL_PATH)/snap
-SNAP_INCLUDES := $(SNAP_DIR)/include
-
-ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
-SNAP_LIB_PATH := $(SNAP_DIR)/lib
-else
-$(error Target arch ABI not supported: $(TARGET_ARCH_ABI))
-endif
-
-#------------------------------------------------------
-# snap-sdk (prebuilt shared library)
-#------------------------------------------------------
-include $(LOCAL_PATH)/Android-snap-prebuilt.mk
-
-#------------------------------------------------------
-# tensor-filter sub-plugin for snap
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := snap-subplugin
-LOCAL_SRC_FILES := $(NNSTREAMER_FILTER_SNAP_SRCS)
-LOCAL_CXXFLAGS := -std=c++11 -O3 -fPIC -frtti -fexceptions $(NNS_API_FLAGS)
-LOCAL_C_INCLUDES := $(SNAP_INCLUDES) $(NNSTREAMER_INCLUDES) $(GST_HEADERS_COMMON)
-LOCAL_STATIC_LIBRARIES := nnstreamer
-LOCAL_SHARED_LIBRARIES := $(SNAP_PREBUILT_LIBS)
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/api/android/api/src/main/jni/Android-snpe-prebuilt.mk b/api/android/api/src/main/jni/Android-snpe-prebuilt.mk
deleted file mode 100644 (file)
index 6d450f8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#------------------------------------------------------
-# SNPE (The Snapdragon Neural Processing Engine)
-#
-# This mk file defines prebuilt libraries for snpe module.
-# (snpe-sdk, arm64-v8a only)
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef SNPE_LIB_PATH
-$(error SNPE_LIB_PATH is not defined!)
-endif
-
-SNPE_PREBUILT_LIBS :=
-
-#------------------------------------------------------
-# snpe-sdk (prebuilt shared library)
-#------------------------------------------------------
-include $(CLEAR_VARS)
-LOCAL_MODULE := libSNPE
-LOCAL_SRC_FILES := $(SNPE_LIB_PATH)/libSNPE.so
-include $(PREBUILT_SHARED_LIBRARY)
-SNPE_PREBUILT_LIBS += libSNPE
diff --git a/api/android/api/src/main/jni/Android-snpe.mk b/api/android/api/src/main/jni/Android-snpe.mk
deleted file mode 100644 (file)
index 0a1b125..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#------------------------------------------------------
-# SNPE (The Snapdragon Neural Processing Engine)
-#
-# This mk file defines snpe module with prebuilt shared library.
-# (snpe-sdk, arm64-v8a only)
-# See Qualcomm Neural Processing SDK for AI (https://developer.qualcomm.com/software/qualcomm-neural-processing-sdk) for the details.
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
-endif
-
-include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
-
-SNPE_DIR := $(LOCAL_PATH)/snpe
-SNPE_INCLUDES := $(SNPE_DIR)/include/zdl/
-
-ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
-SNPE_LIB_PATH := $(SNPE_DIR)/lib
-else
-$(error Target arch ABI not supported: $(TARGET_ARCH_ABI))
-endif
-
-#------------------------------------------------------
-# snpe-sdk (prebuilt shared library)
-#------------------------------------------------------
-include $(LOCAL_PATH)/Android-snpe-prebuilt.mk
-
-#------------------------------------------------------
-# tensor-filter sub-plugin for snpe
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := snpe-subplugin
-LOCAL_SRC_FILES := $(NNSTREAMER_FILTER_SNPE_SRCS)
-LOCAL_CXXFLAGS := -std=c++11 -O3 -fPIC -frtti -fexceptions $(NNS_API_FLAGS)
-LOCAL_C_INCLUDES := $(SNPE_INCLUDES) $(NNSTREAMER_INCLUDES) $(GST_HEADERS_COMMON)
-LOCAL_STATIC_LIBRARIES := nnstreamer
-LOCAL_SHARED_LIBRARIES := $(SNPE_PREBUILT_LIBS)
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/api/android/api/src/main/jni/Android-tensorflow-lite.mk b/api/android/api/src/main/jni/Android-tensorflow-lite.mk
deleted file mode 100644 (file)
index 719d923..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-#------------------------------------------------------
-# tensorflow-lite
-#
-# This mk file defines tensorflow-lite module with prebuilt static library.
-# To build and run the example with gstreamer binaries, we built a static library (e.g., libtensorflow-lite.a)
-# for Android/Tensorflow-lite from the Tensorflow repository of the Tizen software platform.
-# - [Tizen] Tensorflow git repository:
-#    * Repository: https://review.tizen.org/gerrit/p/platform/upstream/tensorflow
-#------------------------------------------------------
-LOCAL_PATH := $(call my-dir)
-
-ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
-endif
-
-include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
-
-TFLITE_VERSION := 1.13.1
-
-_TFLITE_VERSIONS = $(subst ., , $(TFLITE_VERSION))
-TFLITE_VERSION_MAJOR := $(word 1, $(_TFLITE_VERSIONS))
-TFLITE_VERSION_MINOR := $(word 2, $(_TFLITE_VERSIONS))
-TFLITE_VERSION_MICRO := $(word 3, $(_TFLITE_VERSIONS))
-
-TFLITE_FLAGS := \
-    -DTFLITE_SUBPLUGIN_NAME=\"tensorflow-lite\" \
-    -DTFLITE_VERSION=$(TFLITE_VERSION) \
-    -DTFLITE_VERSION_MAJOR=$(TFLITE_VERSION_MAJOR) \
-    -DTFLITE_VERSION_MINOR=$(TFLITE_VERSION_MINOR) \
-    -DTFLITE_VERSION_MICRO=$(TFLITE_VERSION_MICRO)
-
-# Define types and features in tensorflow-lite sub-plugin.
-# FLOAT16/COMPLEX64 for tensorflow-lite >= 2, and INT8/INT16 for tensorflow-lite >=1.13
-# GPU-delegate supported on tensorflow-lite >= 2
-# NNAPI-delegate supported on tensorflow-lite >= 1.14
-TFLITE_ENABLE_GPU_DELEGATE := false
-TFLITE_ENABLE_NNAPI_DELEGATE := false
-TFLITE_EXPORT_LDLIBS :=
-
-ifeq ($(shell test $(TFLITE_VERSION_MAJOR) -ge 2; echo $$?),0)
-TFLITE_ENABLE_GPU_DELEGATE := true
-TFLITE_ENABLE_NNAPI_DELEGATE := true
-
-TFLITE_FLAGS += -DTFLITE_INT8=1 -DTFLITE_INT16=1 -DTFLITE_FLOAT16=1 -DTFLITE_COMPLEX64=1
-else
-ifeq ($(shell test $(TFLITE_VERSION_MINOR) -ge 14; echo $$?),0)
-TFLITE_ENABLE_NNAPI_DELEGATE := true
-endif
-
-ifeq ($(shell test $(TFLITE_VERSION_MINOR) -ge 13; echo $$?),0)
-TFLITE_FLAGS += -DTFLITE_INT8=1 -DTFLITE_INT16=1
-endif
-endif
-
-ifeq ($(TFLITE_ENABLE_NNAPI_DELEGATE),true)
-TFLITE_FLAGS += -DTFLITE_NNAPI_DELEGATE_SUPPORTED=1
-endif
-
-ifeq ($(TFLITE_ENABLE_GPU_DELEGATE),true)
-TFLITE_FLAGS += -DTFLITE_GPU_DELEGATE_SUPPORTED=1
-TFLITE_EXPORT_LDLIBS += -lEGL -lGLESv2
-endif
-
-TF_LITE_DIR := $(LOCAL_PATH)/tensorflow-lite
-TF_LITE_INCLUDES := $(TF_LITE_DIR)/include
-
-ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
-TF_LITE_LIB_PATH := $(TF_LITE_DIR)/lib/armv7
-else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
-TF_LITE_LIB_PATH := $(TF_LITE_DIR)/lib/arm64
-else
-$(error Target arch ABI not supported: $(TARGET_ARCH_ABI))
-endif
-
-#------------------------------------------------------
-# tensorflow-lite (prebuilt static library)
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := tensorflow-lite-lib
-LOCAL_SRC_FILES := $(TF_LITE_LIB_PATH)/libtensorflow-lite.a
-LOCAL_EXPORT_LDFLAGS := -Wl,--exclude-libs,libtensorflow-lite.a
-
-include $(PREBUILT_STATIC_LIBRARY)
-
-#------------------------------------------------------
-# tensor-filter sub-plugin for tensorflow-lite
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := tensorflow-lite-subplugin
-LOCAL_SRC_FILES := $(NNSTREAMER_FILTER_TFLITE_SRCS)
-LOCAL_CXXFLAGS := -std=c++11 -O3 -fPIC -frtti -fexceptions $(NNS_API_FLAGS) $(TFLITE_FLAGS)
-LOCAL_C_INCLUDES := $(TF_LITE_INCLUDES) $(NNSTREAMER_INCLUDES) $(GST_HEADERS_COMMON)
-LOCAL_EXPORT_LDLIBS := $(TFLITE_EXPORT_LDLIBS)
-LOCAL_STATIC_LIBRARIES := tensorflow-lite-lib cpufeatures
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/api/android/api/src/main/jni/Android.mk b/api/android/api/src/main/jni/Android.mk
deleted file mode 100644 (file)
index 1cbff29..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-ifndef GSTREAMER_ROOT_ANDROID
-$(error GSTREAMER_ROOT_ANDROID is not defined!)
-endif
-
-ifndef NNSTREAMER_ROOT
-$(error NNSTREAMER_ROOT is not defined!)
-endif
-
-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
-
-#------------------------------------------------------
-# API build option
-#------------------------------------------------------
-include $(NNSTREAMER_ROOT)/jni/nnstreamer.mk
-
-NNSTREAMER_API_OPTION := all
-
-# tensorflow-lite (nnstreamer tf-lite subplugin)
-ENABLE_TF_LITE := false
-
-# SNAP (Samsung Neural Acceleration Platform)
-ENABLE_SNAP := false
-
-# NNFW (On-device neural network inference framework, Samsung Research)
-ENABLE_NNFW := false
-
-# SNPE (Snapdragon Neural Processing Engine)
-ENABLE_SNPE := false
-
-# PyTorch
-ENABLE_PYTORCH := false
-
-# Decoder sub-plugin for flatbuffers support
-ENABLE_DECODER_FLATBUF := false
-
-ifeq ($(ENABLE_SNAP),true)
-ifeq ($(ENABLE_SNPE),true)
-$(error DO NOT enable SNAP and SNPE both. The app would fail to use DSP or NPU runtime.)
-endif
-endif
-
-# Common options
-NNS_API_INCLUDES := \
-    $(NNSTREAMER_INCLUDES) \
-    $(NNSTREAMER_CAPI_INCLUDES) \
-    $(GST_HEADERS_COMMON)
-
-NNS_API_FLAGS := -DVERSION=\"$(NNSTREAMER_VERSION)\"
-NNS_SUBPLUGINS :=
-
-ifeq ($(NNSTREAMER_API_OPTION),single)
-NNS_API_FLAGS += -DNNS_SINGLE_ONLY=1
-endif
-
-#------------------------------------------------------
-# external libs and sub-plugins
-#------------------------------------------------------
-ifeq ($(ENABLE_TF_LITE),true)
-NNS_API_FLAGS += -DENABLE_TENSORFLOW_LITE=1
-NNS_SUBPLUGINS += tensorflow-lite-subplugin
-
-include $(LOCAL_PATH)/Android-tensorflow-lite.mk
-endif
-
-ifeq ($(ENABLE_SNAP),true)
-NNS_API_FLAGS += -DENABLE_SNAP=1
-NNS_SUBPLUGINS += snap-subplugin
-
-include $(LOCAL_PATH)/Android-snap.mk
-endif
-
-ifeq ($(ENABLE_NNFW),true)
-NNS_API_FLAGS += -DENABLE_NNFW=1
-NNS_SUBPLUGINS += nnfw-subplugin
-
-include $(LOCAL_PATH)/Android-nnfw.mk
-endif
-
-ifeq ($(ENABLE_SNPE),true)
-NNS_API_FLAGS += -DENABLE_SNPE=1
-NNS_SUBPLUGINS += snpe-subplugin
-
-include $(LOCAL_PATH)/Android-snpe.mk
-endif
-
-ifeq ($(ENABLE_PYTORCH),true)
-NNS_API_FLAGS += -DENABLE_PYTORCH=1
-NNS_SUBPLUGINS += pytorch-subplugin
-
-include $(LOCAL_PATH)/Android-pytorch.mk
-endif
-
-ifeq ($(ENABLE_DECODER_FLATBUF),true)
-include $(LOCAL_PATH)/Android-dec-flatbuf.mk
-NNS_API_FLAGS += -DENABLE_DEC_FLATBUF=1
-NNS_SUBPLUGINS += flatbuffers-subplugin
-endif
-
-#------------------------------------------------------
-# nnstreamer
-#------------------------------------------------------
-include $(LOCAL_PATH)/Android-nnstreamer.mk
-
-# Remove any duplicates.
-NNS_SUBPLUGINS := $(sort $(NNS_SUBPLUGINS))
-
-#------------------------------------------------------
-# native code for api
-#------------------------------------------------------
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := nnstreamer-native
-
-LOCAL_SRC_FILES := \
-    nnstreamer-native-api.c \
-    nnstreamer-native-singleshot.c
-
-ifneq ($(NNSTREAMER_API_OPTION),single)
-LOCAL_SRC_FILES += \
-    nnstreamer-native-customfilter.c \
-    nnstreamer-native-pipeline.c
-endif
-
-LOCAL_C_INCLUDES := $(NNS_API_INCLUDES)
-LOCAL_CFLAGS := -O3 -fPIC $(NNS_API_FLAGS)
-LOCAL_STATIC_LIBRARIES := nnstreamer $(NNS_SUBPLUGINS)
-LOCAL_SHARED_LIBRARIES := gstreamer_android
-LOCAL_LDLIBS := -llog -landroid
-
-ifneq ($(NNSTREAMER_API_OPTION),single)
-# For amcsrc element
-LOCAL_LDLIBS += -lmediandk
-endif
-
-include $(BUILD_SHARED_LIBRARY)
-
-#------------------------------------------------------
-# gstreamer for android
-#------------------------------------------------------
-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) gio-2.0 gmodule-2.0
-GSTREAMER_EXTRA_LIBS     := $(GST_REQUIRED_LIBS) -liconv
-
-ifeq ($(NNSTREAMER_API_OPTION),all)
-GSTREAMER_EXTRA_LIBS += -lcairo
-endif
-
-GSTREAMER_INCLUDE_FONTS := no
-GSTREAMER_INCLUDE_CA_CERTIFICATES := no
-
-include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer-1.0.mk
-
-#------------------------------------------------------
-# NDK cpu-features
-#------------------------------------------------------
-$(call import-module, android/cpufeatures)
diff --git a/api/android/api/src/main/jni/Application.mk b/api/android/api/src/main/jni/Application.mk
deleted file mode 100644 (file)
index 89c3ce1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Set target ABI in build.gradle (externalNativeBuild - abiFilters)
-APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
-APP_STL := c++_shared
diff --git a/api/android/api/src/main/jni/nnstreamer-native-api.c b/api/android/api/src/main/jni/nnstreamer-native-api.c
deleted file mode 100644 (file)
index e9177cd..0000000
+++ /dev/null
@@ -1,913 +0,0 @@
-/**
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-native-api.c
- * @date       10 July 2019
- * @brief      Native code for NNStreamer API
- * @author     Jaeyun Jung <jy1210.jung@samsung.com>
- * @bug                No known bugs except for NYI items
- */
-
-#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);
-GST_PLUGIN_STATIC_DECLARE (join);
-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);
-#if defined (ENABLE_DEC_FLATBUF)
-extern void init_fb (void);
-#endif /* ENABLE_DEC_FLATBUF */
-#endif
-
-extern void init_filter_cpp (void);
-extern void init_filter_custom (void);
-extern void init_filter_custom_easy (void);
-
-#if defined (ENABLE_TENSORFLOW_LITE)
-extern void init_filter_tflite (void);
-#endif
-#if defined (ENABLE_SNAP)
-extern void init_filter_snap (void);
-#endif
-#if defined (ENABLE_NNFW)
-extern void init_filter_nnfw (void);
-#endif
-#if defined (ENABLE_SNPE)
-extern void init_filter_snpe (JNIEnv * env, jobject context);
-#endif
-#if defined (ENABLE_PYTORCH)
-extern void init_filter_torch (void);
-#endif
-
-/**
- * @brief External function from GStreamer Android.
- */
-extern void gst_android_init (JNIEnv * env, jobject context);
-
-/**
- * @brief Global lock for native functions.
- */
-G_LOCK_DEFINE_STATIC (nns_native_lock);
-
-/**
- * @brief Attach thread with Java VM.
- */
-static JNIEnv *
-nns_attach_current_thread (pipeline_info_s * pipe_info)
-{
-  JNIEnv *env;
-  JavaVM *jvm;
-  JavaVMAttachArgs args;
-
-  g_assert (pipe_info);
-  jvm = pipe_info->jvm;
-
-  args.version = pipe_info->version;
-  args.name = NULL;
-  args.group = NULL;
-
-  if ((*jvm)->AttachCurrentThread (jvm, &env, &args) < 0) {
-    nns_loge ("Failed to attach current thread.");
-    return NULL;
-  }
-
-  return env;
-}
-
-/**
- * @brief Get JNI environment.
- */
-JNIEnv *
-nns_get_jni_env (pipeline_info_s * pipe_info)
-{
-  JNIEnv *env;
-
-  g_assert (pipe_info);
-
-  if ((env = pthread_getspecific (pipe_info->jni_env)) == NULL) {
-    env = nns_attach_current_thread (pipe_info);
-    pthread_setspecific (pipe_info->jni_env, env);
-  }
-
-  return env;
-}
-
-/**
- * @brief Free element handle pointer.
- */
-void
-nns_free_element_data (gpointer data)
-{
-  element_data_s *item = (element_data_s *) data;
-
-  if (item) {
-    /* release private data */
-    if (item->priv_data) {
-      JNIEnv *env = nns_get_jni_env (item->pipe_info);
-      item->priv_destroy_func (item->priv_data, env);
-    }
-
-    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;
-      case NNS_ELEMENT_TYPE_SINK:
-        ml_pipeline_sink_unregister ((ml_pipeline_sink_h) item->handle);
-        break;
-      case NNS_ELEMENT_TYPE_VALVE:
-        ml_pipeline_valve_release_handle ((ml_pipeline_valve_h) item->handle);
-        break;
-      case NNS_ELEMENT_TYPE_SWITCH:
-        ml_pipeline_switch_release_handle ((ml_pipeline_switch_h) item->handle);
-        break;
-      case NNS_ELEMENT_TYPE_VIDEO_SINK:
-        ml_pipeline_element_release_handle ((ml_pipeline_element_h) item->handle);
-        break;
-#endif
-      default:
-        nns_logw ("Given element type %d is unknown.", item->type);
-        if (item->handle)
-          g_free (item->handle);
-        break;
-    }
-
-    g_free (item->name);
-    g_free (item);
-  }
-}
-
-/**
- * @brief Construct TensorsData class info.
- */
-static void
-nns_construct_tdata_class_info (JNIEnv * env, data_class_info_s * info)
-{
-  jclass cls;
-
-  cls = (*env)->FindClass (env, NNS_CLS_TDATA);
-  info->cls = (*env)->NewGlobalRef (env, cls);
-  (*env)->DeleteLocalRef (env, cls);
-
-  info->mid_init = (*env)->GetMethodID (env, info->cls, "<init>",
-      "(L" NNS_CLS_TINFO ";)V");
-  info->mid_alloc = (*env)->GetStaticMethodID (env, info->cls, "allocate",
-      "(L" NNS_CLS_TINFO ";)L" NNS_CLS_TDATA ";");
-  info->mid_get_array = (*env)->GetMethodID (env, info->cls, "getDataArray",
-      "()[Ljava/lang/Object;");
-  info->mid_get_info = (*env)->GetMethodID (env, info->cls, "getTensorsInfo",
-      "()L" NNS_CLS_TINFO ";");
-}
-
-/**
- * @brief Destroy TensorsData class info.
- */
-static void
-nns_destroy_tdata_class_info (JNIEnv * env, data_class_info_s * info)
-{
-  if (info->cls)
-    (*env)->DeleteGlobalRef (env, info->cls);
-}
-
-/**
- * @brief Construct TensorsInfo class info.
- */
-static void
-nns_construct_tinfo_class_info (JNIEnv * env, info_class_info_s * info)
-{
-  jclass cls;
-
-  cls = (*env)->FindClass (env, NNS_CLS_TINFO);
-  info->cls = (*env)->NewGlobalRef (env, cls);
-  (*env)->DeleteLocalRef (env, cls);
-
-  cls = (*env)->FindClass (env, NNS_CLS_TINFO "$TensorInfo");
-  info->cls_info = (*env)->NewGlobalRef (env, cls);
-  (*env)->DeleteLocalRef (env, cls);
-
-  info->mid_init = (*env)->GetMethodID (env, info->cls, "<init>", "()V");
-  info->mid_add_info = (*env)->GetMethodID (env, info->cls, "appendInfo",
-      "(Ljava/lang/String;I[I)V");
-  info->mid_get_array = (*env)->GetMethodID (env, info->cls, "getInfoArray",
-      "()[Ljava/lang/Object;");
-
-  info->fid_info_name = (*env)->GetFieldID (env, info->cls_info, "name",
-      "Ljava/lang/String;");
-  info->fid_info_type = (*env)->GetFieldID (env, info->cls_info, "type", "I");
-  info->fid_info_dim = (*env)->GetFieldID (env, info->cls_info, "dimension",
-      "[I");
-}
-
-/**
- * @brief Destroy TensorsInfo class info.
- */
-static void
-nns_destroy_tinfo_class_info (JNIEnv * env, info_class_info_s * info)
-{
-  if (info->cls_info)
-    (*env)->DeleteGlobalRef (env, info->cls_info);
-  if (info->cls)
-    (*env)->DeleteGlobalRef (env, info->cls);
-}
-
-/**
- * @brief Construct pipeline info.
- */
-gpointer
-nns_construct_pipe_info (JNIEnv * env, jobject thiz, gpointer handle,
-    nns_pipe_type_e type)
-{
-  pipeline_info_s *pipe_info;
-  jclass cls;
-
-  pipe_info = g_new0 (pipeline_info_s, 1);
-  g_return_val_if_fail (pipe_info != NULL, NULL);
-
-  pipe_info->pipeline_type = type;
-  pipe_info->pipeline_handle = handle;
-  pipe_info->element_handles =
-      g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
-      nns_free_element_data);
-  g_mutex_init (&pipe_info->lock);
-
-  (*env)->GetJavaVM (env, &pipe_info->jvm);
-  g_assert (pipe_info->jvm);
-  pthread_key_create (&pipe_info->jni_env, NULL);
-
-  pipe_info->version = (*env)->GetVersion (env);
-  pipe_info->instance = (*env)->NewGlobalRef (env, thiz);
-
-  cls = (*env)->GetObjectClass (env, pipe_info->instance);
-  pipe_info->cls = (*env)->NewGlobalRef (env, cls);
-  (*env)->DeleteLocalRef (env, cls);
-
-  nns_construct_tdata_class_info (env, &pipe_info->data_cls_info);
-  nns_construct_tinfo_class_info (env, &pipe_info->info_cls_info);
-
-  return pipe_info;
-}
-
-/**
- * @brief Destroy pipeline info.
- */
-void
-nns_destroy_pipe_info (pipeline_info_s * pipe_info, JNIEnv * env)
-{
-  g_return_if_fail (pipe_info != NULL);
-
-  g_mutex_lock (&pipe_info->lock);
-  if (pipe_info->priv_data) {
-    if (pipe_info->priv_destroy_func)
-      pipe_info->priv_destroy_func (pipe_info->priv_data, env);
-    else
-      g_free (pipe_info->priv_data);
-
-    pipe_info->priv_data = NULL;
-  }
-
-  g_hash_table_destroy (pipe_info->element_handles);
-  pipe_info->element_handles = NULL;
-  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_CUSTOM:
-      ml_pipeline_custom_easy_filter_unregister (pipe_info->pipeline_handle);
-      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)
-        g_free (pipe_info->pipeline_handle);
-      break;
-  }
-
-  g_mutex_clear (&pipe_info->lock);
-
-  nns_destroy_tdata_class_info (env, &pipe_info->data_cls_info);
-  nns_destroy_tinfo_class_info (env, &pipe_info->info_cls_info);
-  (*env)->DeleteGlobalRef (env, pipe_info->cls);
-  (*env)->DeleteGlobalRef (env, pipe_info->instance);
-
-  pthread_key_delete (pipe_info->jni_env);
-  g_free (pipe_info);
-}
-
-/**
- * @brief Set private data in pipeline info. If destroy_func is NULL, priv_data will be released using g_free().
- */
-void
-nns_set_priv_data (pipeline_info_s * pipe_info, gpointer data,
-    nns_priv_destroy destroy_func)
-{
-  g_return_if_fail (pipe_info != NULL);
-
-  g_mutex_lock (&pipe_info->lock);
-  pipe_info->priv_data = data;
-  pipe_info->priv_destroy_func = destroy_func;
-  g_mutex_unlock (&pipe_info->lock);
-}
-
-/**
- * @brief Get element data of given name.
- */
-element_data_s *
-nns_get_element_data (pipeline_info_s * pipe_info, const gchar * name)
-{
-  element_data_s *item;
-
-  g_return_val_if_fail (pipe_info, NULL);
-  g_return_val_if_fail (name, NULL);
-
-  g_mutex_lock (&pipe_info->lock);
-  item = g_hash_table_lookup (pipe_info->element_handles, name);
-  g_mutex_unlock (&pipe_info->lock);
-
-  return item;
-}
-
-/**
- * @brief Get element handle of given name and type.
- */
-gpointer
-nns_get_element_handle (pipeline_info_s * pipe_info, const gchar * name,
-    const nns_element_type_e type)
-{
-  element_data_s *item = nns_get_element_data (pipe_info, name);
-
-  /* check element type */
-  return (item && item->type == type) ? item->handle : NULL;
-}
-
-/**
- * @brief Remove element data of given name.
- */
-gboolean
-nns_remove_element_data (pipeline_info_s * pipe_info, const gchar * name)
-{
-  gboolean ret;
-
-  g_return_val_if_fail (pipe_info, FALSE);
-  g_return_val_if_fail (name, FALSE);
-
-  g_mutex_lock (&pipe_info->lock);
-  ret = g_hash_table_remove (pipe_info->element_handles, name);
-  g_mutex_unlock (&pipe_info->lock);
-
-  return ret;
-}
-
-/**
- * @brief Add new element data of given name.
- */
-gboolean
-nns_add_element_data (pipeline_info_s * pipe_info, const gchar * name,
-    element_data_s * item)
-{
-  gboolean ret;
-
-  g_return_val_if_fail (pipe_info, FALSE);
-  g_return_val_if_fail (name && item, FALSE);
-
-  g_mutex_lock (&pipe_info->lock);
-  ret = g_hash_table_insert (pipe_info->element_handles, g_strdup (name), item);
-  g_mutex_unlock (&pipe_info->lock);
-
-  return ret;
-}
-
-/**
- * @brief Create new data object with given tensors info. Caller should unref the result object.
- */
-gboolean
-nns_create_tensors_data_object (pipeline_info_s * pipe_info, JNIEnv * env,
-    jobject obj_info, jobject * result)
-{
-  data_class_info_s *dcls_info;
-  jobject obj_data;
-
-  g_return_val_if_fail (pipe_info, FALSE);
-  g_return_val_if_fail (env, FALSE);
-  g_return_val_if_fail (result, FALSE);
-  g_return_val_if_fail (obj_info, FALSE);
-
-  dcls_info = &pipe_info->data_cls_info;
-  *result = NULL;
-
-  obj_data = (*env)->CallStaticObjectMethod (env, dcls_info->cls,
-      dcls_info->mid_alloc, obj_info);
-  if ((*env)->ExceptionCheck (env) || !obj_data) {
-    nns_loge ("Failed to allocate object for tensors data.");
-    (*env)->ExceptionClear (env);
-
-    if (obj_data)
-      (*env)->DeleteLocalRef (env, obj_data);
-
-    return FALSE;
-  }
-
-  *result = obj_data;
-  return TRUE;
-}
-
-/**
- * @brief Convert tensors data to TensorsData object.
- */
-gboolean
-nns_convert_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env,
-    ml_tensors_data_h data_h, jobject obj_info, jobject * result)
-{
-  guint i;
-  data_class_info_s *dcls_info;
-  jobject obj_data = NULL;
-  jobjectArray data_arr;
-  ml_tensors_data_s *data;
-
-  g_return_val_if_fail (pipe_info, FALSE);
-  g_return_val_if_fail (env, FALSE);
-  g_return_val_if_fail (data_h, FALSE);
-  g_return_val_if_fail (result, FALSE);
-  g_return_val_if_fail (obj_info, FALSE);
-
-  dcls_info = &pipe_info->data_cls_info;
-  data = (ml_tensors_data_s *) data_h;
-  *result = NULL;
-
-  if (!nns_create_tensors_data_object (pipe_info, env, obj_info, &obj_data))
-    return FALSE;
-
-  data_arr = (*env)->CallObjectMethod (env, obj_data, dcls_info->mid_get_array);
-
-  for (i = 0; i < data->num_tensors; i++) {
-    jobject tensor = (*env)->GetObjectArrayElement (env, data_arr, i);
-    gpointer data_ptr = (*env)->GetDirectBufferAddress (env, tensor);
-
-    memcpy (data_ptr, data->tensors[i].tensor, data->tensors[i].size);
-    (*env)->DeleteLocalRef (env, tensor);
-  }
-
-  (*env)->DeleteLocalRef (env, data_arr);
-
-  *result = obj_data;
-  return TRUE;
-}
-
-/**
- * @brief Parse tensors data from TensorsData object.
- */
-gboolean
-nns_parse_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env,
-    jobject obj_data, gboolean clone, ml_tensors_data_h * data_h,
-    ml_tensors_info_h * info_h)
-{
-  guint i;
-  data_class_info_s *dcls_info;
-  ml_tensors_data_s *data;
-  jobjectArray data_arr;
-  gboolean failed = FALSE;
-
-  g_return_val_if_fail (pipe_info, FALSE);
-  g_return_val_if_fail (env, FALSE);
-  g_return_val_if_fail (obj_data, FALSE);
-  g_return_val_if_fail (data_h, FALSE);
-
-  if (*data_h == NULL &&
-      ml_tensors_data_create_no_alloc (NULL, data_h) != ML_ERROR_NONE) {
-    nns_loge ("Failed to create handle for tensors data.");
-    return FALSE;
-  }
-
-  dcls_info = &pipe_info->data_cls_info;
-  data = (ml_tensors_data_s *) (*data_h);
-
-  data_arr = (*env)->CallObjectMethod (env, obj_data, dcls_info->mid_get_array);
-
-  /* number of tensors data */
-  data->num_tensors = (unsigned int) (*env)->GetArrayLength (env, data_arr);
-
-  /* set tensor data */
-  for (i = 0; i < data->num_tensors; i++) {
-    jobject tensor = (*env)->GetObjectArrayElement (env, data_arr, i);
-
-    if (tensor) {
-      gsize data_size = (gsize) (*env)->GetDirectBufferCapacity (env, tensor);
-      gpointer data_ptr = (*env)->GetDirectBufferAddress (env, tensor);
-
-      if (clone) {
-        if (data->tensors[i].tensor == NULL)
-          data->tensors[i].tensor = g_malloc (data_size);
-
-        memcpy (data->tensors[i].tensor, data_ptr, data_size);
-      } else {
-        data->tensors[i].tensor = data_ptr;
-      }
-
-      data->tensors[i].size = data_size;
-
-      (*env)->DeleteLocalRef (env, tensor);
-    } else {
-      nns_loge ("Failed to get array element in tensors data object.");
-      failed = TRUE;
-      goto done;
-    }
-  }
-
-  /* parse tensors info in data class */
-  if (info_h) {
-    jobject obj_info =
-        (*env)->CallObjectMethod (env, obj_data, dcls_info->mid_get_info);
-
-    if (obj_info) {
-      nns_parse_tensors_info (pipe_info, env, obj_info, info_h);
-      (*env)->DeleteLocalRef (env, obj_info);
-    }
-  }
-
-done:
-  (*env)->DeleteLocalRef (env, data_arr);
-
-  if (failed) {
-    ml_tensors_data_destroy (*data_h);
-    *data_h = NULL;
-  }
-
-  return !failed;
-}
-
-/**
- * @brief Convert tensors info to TensorsInfo object.
- */
-gboolean
-nns_convert_tensors_info (pipeline_info_s * pipe_info, JNIEnv * env,
-    ml_tensors_info_h info_h, jobject * result)
-{
-  guint i;
-  info_class_info_s *icls_info;
-  ml_tensors_info_s *info;
-  jobject obj_info = NULL;
-
-  g_return_val_if_fail (pipe_info, FALSE);
-  g_return_val_if_fail (env, FALSE);
-  g_return_val_if_fail (info_h, FALSE);
-  g_return_val_if_fail (result, FALSE);
-
-  icls_info = &pipe_info->info_cls_info;
-  info = (ml_tensors_info_s *) info_h;
-
-  obj_info = (*env)->NewObject (env, icls_info->cls, icls_info->mid_init);
-  if (!obj_info) {
-    nns_loge ("Failed to allocate object for tensors info.");
-    goto done;
-  }
-
-  for (i = 0; i < info->num_tensors; i++) {
-    jstring name = NULL;
-    jint type;
-    jintArray dimension;
-
-    if (info->info[i].name)
-      name = (*env)->NewStringUTF (env, info->info[i].name);
-
-    type = (jint) info->info[i].type;
-
-    dimension = (*env)->NewIntArray (env, ML_TENSOR_RANK_LIMIT);
-    (*env)->SetIntArrayRegion (env, dimension, 0, ML_TENSOR_RANK_LIMIT,
-        (jint *) info->info[i].dimension);
-
-    (*env)->CallVoidMethod (env, obj_info, icls_info->mid_add_info,
-        name, type, dimension);
-
-    if (name)
-      (*env)->DeleteLocalRef (env, name);
-    (*env)->DeleteLocalRef (env, dimension);
-  }
-
-done:
-  *result = obj_info;
-  return (obj_info != NULL);
-}
-
-/**
- * @brief Parse tensors info from TensorsInfo object.
- */
-gboolean
-nns_parse_tensors_info (pipeline_info_s * pipe_info, JNIEnv * env,
-    jobject obj_info, ml_tensors_info_h * info_h)
-{
-  guint i;
-  info_class_info_s *icls_info;
-  ml_tensors_info_s *info;
-  jobjectArray info_arr;
-
-  g_return_val_if_fail (pipe_info, FALSE);
-  g_return_val_if_fail (env, FALSE);
-  g_return_val_if_fail (obj_info, FALSE);
-  g_return_val_if_fail (info_h, FALSE);
-
-  if (ml_tensors_info_create (info_h) != ML_ERROR_NONE) {
-    nns_loge ("Failed to create handle for tensors info.");
-    return FALSE;
-  }
-
-  icls_info = &pipe_info->info_cls_info;
-  info = (ml_tensors_info_s *) (*info_h);
-
-  info_arr = (*env)->CallObjectMethod (env, obj_info, icls_info->mid_get_array);
-
-  /* number of tensors info */
-  info->num_tensors = (unsigned int) (*env)->GetArrayLength (env, info_arr);
-
-  /* read tensor info */
-  for (i = 0; i < info->num_tensors; i++) {
-    jobject item = (*env)->GetObjectArrayElement (env, info_arr, i);
-
-    /* tensor name */
-    jstring name_str = (jstring) (*env)->GetObjectField (env, item,
-        icls_info->fid_info_name);
-    if (name_str) {
-      const gchar *name = (*env)->GetStringUTFChars (env, name_str, NULL);
-
-      info->info[i].name = g_strdup (name);
-      (*env)->ReleaseStringUTFChars (env, name_str, name);
-      (*env)->DeleteLocalRef (env, name_str);
-    }
-
-    /* tensor type */
-    info->info[i].type = (ml_tensor_type_e) (*env)->GetIntField (env, item,
-        icls_info->fid_info_type);
-
-    /* tensor dimension */
-    jintArray dimension = (jintArray) (*env)->GetObjectField (env, item,
-        icls_info->fid_info_dim);
-    (*env)->GetIntArrayRegion (env, dimension, 0, ML_TENSOR_RANK_LIMIT,
-        (jint *) info->info[i].dimension);
-    (*env)->DeleteLocalRef (env, dimension);
-
-    (*env)->DeleteLocalRef (env, item);
-  }
-
-  (*env)->DeleteLocalRef (env, info_arr);
-  return TRUE;
-}
-
-/**
- * @brief Get NNFW from integer value.
- */
-gboolean
-nns_get_nnfw_type (jint fw_type, ml_nnfw_type_e * nnfw)
-{
-  gboolean is_supported = TRUE;
-
-  if (!nnfw)
-    return FALSE;
-
-  *nnfw = ML_NNFW_TYPE_ANY;
-
-  /* enumeration defined in NNStreamer.java */
-  switch (fw_type) {
-    case 0: /* NNFWType.TENSORFLOW_LITE */
-      *nnfw = ML_NNFW_TYPE_TENSORFLOW_LITE;
-#if !defined (ENABLE_TENSORFLOW_LITE)
-      nns_logw ("tensorflow-lite is not supported.");
-      is_supported = FALSE;
-#endif
-      break;
-    case 1: /* NNFWType.SNAP */
-      *nnfw = ML_NNFW_TYPE_SNAP;
-#if !defined (ENABLE_SNAP)
-      nns_logw ("SNAP is not supported.");
-      is_supported = FALSE;
-#endif
-      break;
-    case 2: /* NNFWType.NNFW */
-      *nnfw = ML_NNFW_TYPE_NNFW;
-#if !defined (ENABLE_NNFW)
-      nns_logw ("NNFW is not supported.");
-      is_supported = FALSE;
-#endif
-      break;
-    case 3: /* NNFWType.SNPE */
-      *nnfw = ML_NNFW_TYPE_SNPE;
-#if !defined (ENABLE_SNPE)
-      nns_logw ("SNPE is not supported.");
-      is_supported = FALSE;
-#endif
-      break;
-    case 4: /* NNFWType.PYTORCH */
-      *nnfw = ML_NNFW_TYPE_PYTORCH;
-#if !defined (ENABLE_PYTORCH)
-      nns_logw ("PYTORCH is not supported.");
-      is_supported = FALSE;
-#endif
-      break;
-    default: /* Unknown */
-      nns_logw ("Unknown NNFW type (%d).", fw_type);
-      is_supported = FALSE;
-      break;
-  }
-
-  return is_supported && ml_nnfw_is_available (*nnfw, ML_NNFW_HW_ANY);
-}
-
-/**
- * @brief Initialize NNStreamer, register required plugins.
- */
-jboolean
-nnstreamer_native_initialize (JNIEnv * env, jobject context)
-{
-  jboolean result = JNI_FALSE;
-  static gboolean nns_is_initilaized = FALSE;
-
-  nns_logi ("Called native initialize.");
-
-  G_LOCK (nns_native_lock);
-
-#if !defined (NNS_SINGLE_ONLY)
-  /* single-shot does not require gstreamer */
-  if (!gst_is_initialized ()) {
-    if (env && context) {
-      gst_android_init (env, context);
-    } else {
-      nns_loge ("Invalid params, cannot initialize GStreamer.");
-      goto done;
-    }
-  }
-
-  if (!gst_is_initialized ()) {
-    nns_loge ("GStreamer is not initialized.");
-    goto done;
-  }
-#endif
-
-  if (nns_is_initilaized == FALSE) {
-    /* register nnstreamer plugins */
-#if !defined (NNS_SINGLE_ONLY)
-    GST_PLUGIN_STATIC_REGISTER (nnstreamer);
-
-    /* Android MediaCodec */
-    GST_PLUGIN_STATIC_REGISTER (amcsrc);
-
-    /* GStreamer join element */
-    GST_PLUGIN_STATIC_REGISTER (join);
-
-    /* tensor-decoder sub-plugins */
-    init_dv ();
-    init_bb ();
-    init_il ();
-    init_pose ();
-    init_is ();
-#if defined (ENABLE_DEC_FLATBUF)
-    init_fb ();
-#endif /* ENABLE_DEC_FLATBUF */
-#endif
-
-    /* tensor-filter sub-plugins */
-    init_filter_cpp ();
-    init_filter_custom ();
-    init_filter_custom_easy ();
-
-#if defined (ENABLE_TENSORFLOW_LITE)
-    init_filter_tflite ();
-#endif
-#if defined (ENABLE_SNAP)
-    init_filter_snap ();
-#endif
-#if defined (ENABLE_NNFW)
-    init_filter_nnfw ();
-#endif
-#if defined (ENABLE_SNPE)
-    init_filter_snpe (env, context);
-#endif
-#if defined (ENABLE_PYTORCH)
-    init_filter_torch ();
-#endif
-
-    nns_is_initilaized = TRUE;
-  }
-
-  result = JNI_TRUE;
-
-  /* print version info */
-  gchar *gst_ver = gst_version_string ();
-  gchar *nns_ver = nnstreamer_version_string ();
-
-  nns_logi ("%s %s GLib %d.%d.%d", nns_ver, gst_ver, GLIB_MAJOR_VERSION,
-      GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
-
-  g_free (gst_ver);
-  g_free (nns_ver);
-
-done:
-  G_UNLOCK (nns_native_lock);
-  return result;
-}
-
-/**
- * @brief Native method to initialize NNStreamer.
- */
-static jboolean
-nns_native_initialize (JNIEnv * env, jclass clazz, jobject context)
-{
-  return nnstreamer_native_initialize (env, context);
-}
-
-/**
- * @brief Native method to check the availability of NNFW.
- */
-static jboolean
-nns_native_check_nnfw_availability (JNIEnv * env, jclass clazz, jint fw_type)
-{
-  ml_nnfw_type_e nnfw;
-
-  if (!nns_get_nnfw_type (fw_type, &nnfw)) {
-    return JNI_FALSE;
-  }
-
-  return JNI_TRUE;
-}
-
-/**
- * @brief Native method to get the version string of NNStreamer.
- */
-static jstring
-nns_native_get_version (JNIEnv * env, jclass clazz)
-{
-  gchar *nns_ver = nnstreamer_version_string ();
-  jstring version = (*env)->NewStringUTF (env, nns_ver);
-
-  g_free (nns_ver);
-  return version;
-}
-
-/**
- * @brief List of implemented native methods for NNStreamer class.
- */
-static JNINativeMethod native_methods_nnstreamer[] = {
-  {"nativeInitialize", "(Landroid/content/Context;)Z",
-      (void *) nns_native_initialize},
-  {"nativeCheckNNFWAvailability", "(I)Z",
-      (void *) nns_native_check_nnfw_availability},
-  {"nativeGetVersion", "()Ljava/lang/String;", (void *) nns_native_get_version}
-};
-
-/**
- * @brief Initialize native library.
- */
-jint
-JNI_OnLoad (JavaVM * vm, void *reserved)
-{
-  JNIEnv *env = NULL;
-  jclass klass;
-
-  if ((*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) {
-    nns_loge ("On initializing, failed to get JNIEnv.");
-    return 0;
-  }
-
-  klass = (*env)->FindClass (env, NNS_CLS_NNSTREAMER);
-  if (klass) {
-    if ((*env)->RegisterNatives (env, klass, native_methods_nnstreamer,
-            G_N_ELEMENTS (native_methods_nnstreamer))) {
-      nns_loge ("Failed to register native methods for NNStreamer class.");
-      return 0;
-    }
-  }
-
-  if (!nns_native_single_register_natives (env)) {
-    return 0;
-  }
-
-#if !defined (NNS_SINGLE_ONLY)
-  if (!nns_native_pipe_register_natives (env) ||
-      !nns_native_custom_register_natives (env)) {
-    return 0;
-  }
-#endif
-
-  return JNI_VERSION_1_4;
-}
diff --git a/api/android/api/src/main/jni/nnstreamer-native-customfilter.c b/api/android/api/src/main/jni/nnstreamer-native-customfilter.c
deleted file mode 100644 (file)
index 2a1ac58..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/**
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-native-customfilter.c
- * @date       10 July 2019
- * @brief      Native code for NNStreamer API
- * @author     Jaeyun Jung <jy1210.jung@samsung.com>
- * @bug                No known bugs except for NYI items
- */
-
-#include "nnstreamer-native.h"
-
-/**
- * @brief Private data for CustomFilter class.
- */
-typedef struct
-{
-  jmethodID mid_invoke;
-  ml_tensors_info_h in_info;
-  jobject in_info_obj;
-} customfilter_priv_data_s;
-
-/**
- * @brief Release private data in custom filter.
- */
-static void
-nns_customfilter_priv_free (gpointer data, JNIEnv * env)
-{
-  customfilter_priv_data_s *priv = (customfilter_priv_data_s *) data;
-
-  ml_tensors_info_destroy (priv->in_info);
-  if (priv->in_info_obj)
-    (*env)->DeleteGlobalRef (env, priv->in_info_obj);
-
-  g_free (priv);
-}
-
-/**
- * @brief Update input info in private data.
- */
-static gboolean
-nns_customfilter_priv_set_in_info (pipeline_info_s * pipe_info, JNIEnv * env,
-    ml_tensors_info_h in_info)
-{
-  customfilter_priv_data_s *priv;
-  jobject obj_info = NULL;
-
-  priv = (customfilter_priv_data_s *) pipe_info->priv_data;
-
-  if (ml_tensors_info_is_equal (in_info, priv->in_info)) {
-    /* do nothing, tensors info is equal. */
-    return TRUE;
-  }
-
-  if (!nns_convert_tensors_info (pipe_info, env, in_info, &obj_info)) {
-    nns_loge ("Failed to convert tensors info.");
-    return FALSE;
-  }
-
-  ml_tensors_info_free (priv->in_info);
-  ml_tensors_info_clone (priv->in_info, in_info);
-
-  if (priv->in_info_obj)
-    (*env)->DeleteGlobalRef (env, priv->in_info_obj);
-  priv->in_info_obj = (*env)->NewGlobalRef (env, obj_info);
-  (*env)->DeleteLocalRef (env, obj_info);
-  return TRUE;
-}
-
-/**
- * @brief The mandatory callback for custom-filter execution.
- * @return 0 if OK. 1 to drop input buffer. Negative value if error.
- */
-static int
-nns_customfilter_invoke (const ml_tensors_data_h in, ml_tensors_data_h out,
-    void *user_data)
-{
-  pipeline_info_s *pipe_info = NULL;
-  customfilter_priv_data_s *priv;
-  JNIEnv *env;
-  jobject obj_in_data, obj_out_data;
-  int ret = -1;
-
-  /* get pipe info and init */
-  pipe_info = (pipeline_info_s *) user_data;
-  g_return_val_if_fail (pipe_info, -1);
-
-  env = nns_get_jni_env (pipe_info);
-  g_return_val_if_fail (env, -1);
-
-  obj_in_data = obj_out_data = NULL;
-  priv = (customfilter_priv_data_s *) pipe_info->priv_data;
-
-  /* convert to data object */
-  if (!nns_convert_tensors_data (pipe_info, env, in, priv->in_info_obj,
-          &obj_in_data)) {
-    nns_loge ("Failed to convert input data to data-object.");
-    goto done;
-  }
-
-  /* call invoke callback */
-  obj_out_data = (*env)->CallObjectMethod (env, pipe_info->instance,
-      priv->mid_invoke, obj_in_data);
-
-  if ((*env)->ExceptionCheck (env)) {
-    nns_loge ("Failed to call the custom-invoke callback.");
-    (*env)->ExceptionClear (env);
-    goto done;
-  }
-
-  if (obj_out_data == NULL) {
-    /* drop current buffer */
-    ret = 1;
-    goto done;
-  }
-
-  if (!nns_parse_tensors_data (pipe_info, env, obj_out_data, TRUE, &out, NULL)) {
-    nns_loge ("Failed to parse output data.");
-    goto done;
-  }
-
-  /* callback finished */
-  ret = 0;
-
-done:
-  if (obj_in_data)
-    (*env)->DeleteLocalRef (env, obj_in_data);
-  if (obj_out_data)
-    (*env)->DeleteLocalRef (env, obj_out_data);
-
-  return ret;
-}
-
-/**
- * @brief Native method for custom filter.
- */
-static jlong
-nns_native_custom_initialize (JNIEnv * env, jobject thiz, jstring name,
-    jobject in, jobject out)
-{
-  pipeline_info_s *pipe_info = NULL;
-  customfilter_priv_data_s *priv;
-  ml_custom_easy_filter_h custom;
-  ml_tensors_info_h in_info, out_info;
-  gboolean is_done = FALSE;
-  int status;
-  const char *model_name = (*env)->GetStringUTFChars (env, name, NULL);
-
-  nns_logd ("Try to add custom-filter %s.", model_name);
-  in_info = out_info = NULL;
-
-  pipe_info = nns_construct_pipe_info (env, thiz, NULL, NNS_PIPE_TYPE_CUSTOM);
-  if (pipe_info == NULL) {
-    nns_loge ("Failed to create pipe info.");
-    goto done;
-  }
-
-  priv = g_new0 (customfilter_priv_data_s, 1);
-  priv->mid_invoke = (*env)->GetMethodID (env, pipe_info->cls, "invoke",
-      "(L" NNS_CLS_TDATA ";)L" NNS_CLS_TDATA ";");
-  ml_tensors_info_create (&priv->in_info);
-
-  nns_set_priv_data (pipe_info, priv, nns_customfilter_priv_free);
-
-  if (!nns_parse_tensors_info (pipe_info, env, in, &in_info)) {
-    nns_loge ("Failed to parse input info.");
-    goto done;
-  }
-
-  if (!nns_parse_tensors_info (pipe_info, env, out, &out_info)) {
-    nns_loge ("Failed to parse output info.");
-    goto done;
-  }
-
-  /* update input info */
-  if (!nns_customfilter_priv_set_in_info (pipe_info, env, in_info)) {
-    goto done;
-  }
-
-  status = ml_pipeline_custom_easy_filter_register (model_name,
-      in_info, out_info, nns_customfilter_invoke, pipe_info, &custom);
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to register custom-filter %s.", model_name);
-    goto done;
-  }
-
-  pipe_info->pipeline_handle = custom;
-  is_done = TRUE;
-
-done:
-  (*env)->ReleaseStringUTFChars (env, name, model_name);
-  ml_tensors_info_destroy (in_info);
-  ml_tensors_info_destroy (out_info);
-
-  if (!is_done) {
-    nns_destroy_pipe_info (pipe_info, env);
-    pipe_info = NULL;
-  }
-
-  return CAST_TO_LONG (pipe_info);
-}
-
-/**
- * @brief Native method for custom filter.
- */
-static void
-nns_native_custom_destroy (JNIEnv * env, jobject thiz, jlong handle)
-{
-  pipeline_info_s *pipe_info = NULL;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  nns_destroy_pipe_info (pipe_info, env);
-}
-
-/**
- * @brief List of implemented native methods for CustomFilter class.
- */
-static JNINativeMethod native_methods_customfilter[] = {
-  {"nativeInitialize", "(Ljava/lang/String;L" NNS_CLS_TINFO ";L" NNS_CLS_TINFO ";)J",
-      (void *) nns_native_custom_initialize},
-  {"nativeDestroy", "(J)V", (void *) nns_native_custom_destroy}
-};
-
-/**
- * @brief Register native methods for CustomFilter class.
- */
-gboolean
-nns_native_custom_register_natives (JNIEnv * env)
-{
-  jclass klass = (*env)->FindClass (env, NNS_CLS_CUSTOM_FILTER);
-
-  if (klass) {
-    if ((*env)->RegisterNatives (env, klass, native_methods_customfilter,
-            G_N_ELEMENTS (native_methods_customfilter))) {
-      nns_loge ("Failed to register native methods for CustomFilter class.");
-      return FALSE;
-    }
-  }
-
-  return TRUE;
-}
diff --git a/api/android/api/src/main/jni/nnstreamer-native-pipeline.c b/api/android/api/src/main/jni/nnstreamer-native-pipeline.c
deleted file mode 100644 (file)
index 985cf5d..0000000
+++ /dev/null
@@ -1,965 +0,0 @@
-/**
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-native-pipeline.c
- * @date       10 July 2019
- * @brief      Native code for NNStreamer API
- * @author     Jaeyun Jung <jy1210.jung@samsung.com>
- * @bug                No known bugs except for NYI items
- */
-
-#include "nnstreamer-native.h"
-
-/**
- * @brief Macro to release native window.
- */
-#define release_native_window(w) do { \
-  if (w) { \
-    ANativeWindow_release (w); \
-    w = NULL; \
-  } \
-} while (0)
-
-/**
- * @brief Private data for Pipeline class.
- */
-typedef struct
-{
-  jmethodID mid_state_cb;
-  jmethodID mid_sink_cb;
-} pipeline_priv_data_s;
-
-/**
- * @brief Private data for sink node.
- */
-typedef struct
-{
-  ml_tensors_info_h out_info;
-  jobject out_info_obj;
-} pipeline_sink_priv_data_s;
-
-/**
- * @brief Private data for video sink.
- */
-typedef struct
-{
-  ANativeWindow *window;
-  ANativeWindow *old_window;
-} pipeline_video_sink_priv_data_s;
-
-/**
- * @brief Release private data in pipeline info.
- */
-static void
-nns_pipeline_priv_free (gpointer data, JNIEnv * env)
-{
-  pipeline_priv_data_s *priv = (pipeline_priv_data_s *) data;
-
-  /* nothing to free */
-  g_free (priv);
-}
-
-/**
- * @brief Release private data in video sink.
- */
-static void
-nns_pipeline_video_sink_priv_free (gpointer data, JNIEnv * env)
-{
-  pipeline_video_sink_priv_data_s *priv;
-
-  priv = (pipeline_video_sink_priv_data_s *) data;
-  if (priv) {
-    release_native_window (priv->old_window);
-    release_native_window (priv->window);
-
-    g_free (priv);
-  }
-}
-
-/**
- * @brief Release private data in sink node.
- */
-static void
-nns_pipeline_sink_priv_free (gpointer data, JNIEnv * env)
-{
-  pipeline_sink_priv_data_s *priv = (pipeline_sink_priv_data_s *) data;
-
-  ml_tensors_info_destroy (priv->out_info);
-  if (priv->out_info_obj)
-    (*env)->DeleteGlobalRef (env, priv->out_info_obj);
-
-  g_free (priv);
-}
-
-/**
- * @brief Update output info in sink node data.
- */
-static gboolean
-nns_pipeline_sink_priv_set_out_info (element_data_s * item, JNIEnv * env,
-    const ml_tensors_info_h out_info)
-{
-  pipeline_sink_priv_data_s *priv;
-  jobject obj_info = NULL;
-
-  if ((priv = item->priv_data) == NULL) {
-    priv = g_new0 (pipeline_sink_priv_data_s, 1);
-    ml_tensors_info_create (&priv->out_info);
-
-    item->priv_data = priv;
-    item->priv_destroy_func = nns_pipeline_sink_priv_free;
-  }
-
-  if (ml_tensors_info_is_equal (out_info, priv->out_info)) {
-    /* do nothing, tensors info is equal. */
-    return TRUE;
-  }
-
-  if (!nns_convert_tensors_info (item->pipe_info, env, out_info, &obj_info)) {
-    nns_loge ("Failed to convert output info.");
-    return FALSE;
-  }
-
-  ml_tensors_info_free (priv->out_info);
-  ml_tensors_info_clone (priv->out_info, out_info);
-
-  if (priv->out_info_obj)
-    (*env)->DeleteGlobalRef (env, priv->out_info_obj);
-  priv->out_info_obj = (*env)->NewGlobalRef (env, obj_info);
-  (*env)->DeleteLocalRef (env, obj_info);
-  return TRUE;
-}
-
-/**
- * @brief Pipeline state change callback.
- */
-static void
-nns_pipeline_state_cb (ml_pipeline_state_e state, void *user_data)
-{
-  pipeline_info_s *pipe_info;
-  pipeline_priv_data_s *priv;
-  jint new_state = (jint) state;
-  JNIEnv *env;
-
-  pipe_info = (pipeline_info_s *) user_data;
-  priv = (pipeline_priv_data_s *) pipe_info->priv_data;
-
-  if ((env = nns_get_jni_env (pipe_info)) == NULL) {
-    nns_logw ("Cannot get jni env in the state callback.");
-    return;
-  }
-
-  (*env)->CallVoidMethod (env, pipe_info->instance, priv->mid_state_cb,
-      new_state);
-
-  if ((*env)->ExceptionCheck (env)) {
-    nns_loge ("Failed to call the state-change callback method.");
-    (*env)->ExceptionClear (env);
-  }
-}
-
-/**
- * @brief New data callback for sink node.
- */
-static void
-nns_sink_data_cb (const ml_tensors_data_h data, const ml_tensors_info_h info,
-    void *user_data)
-{
-  element_data_s *item;
-  pipeline_info_s *pipe_info;
-  pipeline_priv_data_s *priv;
-  pipeline_sink_priv_data_s *priv_sink;
-  jobject obj_data = NULL;
-  JNIEnv *env;
-
-  item = (element_data_s *) user_data;
-  pipe_info = item->pipe_info;
-
-  if ((env = nns_get_jni_env (pipe_info)) == NULL) {
-    nns_logw ("Cannot get jni env in the sink callback.");
-    return;
-  }
-
-  /* cache output tensors info */
-  if (!nns_pipeline_sink_priv_set_out_info (item, env, info)) {
-    return;
-  }
-
-  priv = (pipeline_priv_data_s *) pipe_info->priv_data;
-  priv_sink = (pipeline_sink_priv_data_s *) item->priv_data;
-
-  if (nns_convert_tensors_data (pipe_info, env, data, priv_sink->out_info_obj,
-          &obj_data)) {
-    jstring sink_name = (*env)->NewStringUTF (env, item->name);
-
-    (*env)->CallVoidMethod (env, pipe_info->instance, priv->mid_sink_cb,
-        sink_name, obj_data);
-
-    if ((*env)->ExceptionCheck (env)) {
-      nns_loge ("Failed to call the new-data callback method.");
-      (*env)->ExceptionClear (env);
-    }
-
-    (*env)->DeleteLocalRef (env, sink_name);
-    (*env)->DeleteLocalRef (env, obj_data);
-  } else {
-    nns_loge ("Failed to convert the result to data object.");
-  }
-}
-
-/**
- * @brief Get sink handle.
- */
-static void *
-nns_get_sink_handle (pipeline_info_s * pipe_info, const gchar * element_name)
-{
-  const nns_element_type_e etype = NNS_ELEMENT_TYPE_SINK;
-  ml_pipeline_sink_h handle;
-  ml_pipeline_h pipe;
-  int status;
-
-  g_assert (pipe_info);
-  pipe = pipe_info->pipeline_handle;
-
-  handle = (ml_pipeline_sink_h) nns_get_element_handle (pipe_info,
-      element_name, etype);
-  if (handle == NULL) {
-    /* get sink handle and register to table */
-    element_data_s *item = g_new0 (element_data_s, 1);
-    if (item == NULL) {
-      nns_loge ("Failed to allocate memory for sink handle data.");
-      return NULL;
-    }
-
-    status = ml_pipeline_sink_register (pipe, element_name, nns_sink_data_cb,
-        item, &handle);
-    if (status != ML_ERROR_NONE) {
-      nns_loge ("Failed to get sink node %s.", element_name);
-      g_free (item);
-      return NULL;
-    }
-
-    item->name = g_strdup (element_name);
-    item->type = etype;
-    item->handle = handle;
-    item->pipe_info = pipe_info;
-
-    if (!nns_add_element_data (pipe_info, element_name, item)) {
-      nns_loge ("Failed to add sink node %s.", element_name);
-      nns_free_element_data (item);
-      return NULL;
-    }
-  }
-
-  return handle;
-}
-
-/**
- * @brief Get src handle.
- */
-static void *
-nns_get_src_handle (pipeline_info_s * pipe_info, const gchar * element_name)
-{
-  const nns_element_type_e etype = NNS_ELEMENT_TYPE_SRC;
-  ml_pipeline_src_h handle;
-  ml_pipeline_h pipe;
-  int status;
-
-  g_assert (pipe_info);
-  pipe = pipe_info->pipeline_handle;
-
-  handle = (ml_pipeline_src_h) nns_get_element_handle (pipe_info,
-      element_name, etype);
-  if (handle == NULL) {
-    /* get src handle and register to table */
-    status = ml_pipeline_src_get_handle (pipe, element_name, &handle);
-    if (status != ML_ERROR_NONE) {
-      nns_loge ("Failed to get src node %s.", element_name);
-      return NULL;
-    }
-
-    element_data_s *item = g_new0 (element_data_s, 1);
-    if (item == NULL) {
-      nns_loge ("Failed to allocate memory for src handle data.");
-      ml_pipeline_src_release_handle (handle);
-      return NULL;
-    }
-
-    item->name = g_strdup (element_name);
-    item->type = etype;
-    item->handle = handle;
-    item->pipe_info = pipe_info;
-
-    if (!nns_add_element_data (pipe_info, element_name, item)) {
-      nns_loge ("Failed to add src node %s.", element_name);
-      nns_free_element_data (item);
-      return NULL;
-    }
-  }
-
-  return handle;
-}
-
-/**
- * @brief Get switch handle.
- */
-static void *
-nns_get_switch_handle (pipeline_info_s * pipe_info, const gchar * element_name)
-{
-  const nns_element_type_e etype = NNS_ELEMENT_TYPE_SWITCH;
-  ml_pipeline_switch_h handle;
-  ml_pipeline_switch_e switch_type;
-  ml_pipeline_h pipe;
-  int status;
-
-  g_assert (pipe_info);
-  pipe = pipe_info->pipeline_handle;
-
-  handle = (ml_pipeline_switch_h) nns_get_element_handle (pipe_info,
-      element_name, etype);
-  if (handle == NULL) {
-    /* get switch handle and register to table */
-    status = ml_pipeline_switch_get_handle (pipe, element_name, &switch_type,
-        &handle);
-    if (status != ML_ERROR_NONE) {
-      nns_loge ("Failed to get switch %s.", element_name);
-      return NULL;
-    }
-
-    element_data_s *item = g_new0 (element_data_s, 1);
-    if (item == NULL) {
-      nns_loge ("Failed to allocate memory for switch handle data.");
-      ml_pipeline_switch_release_handle (handle);
-      return NULL;
-    }
-
-    item->name = g_strdup (element_name);
-    item->type = etype;
-    item->handle = handle;
-    item->pipe_info = pipe_info;
-
-    if (!nns_add_element_data (pipe_info, element_name, item)) {
-      nns_loge ("Failed to add switch %s.", element_name);
-      nns_free_element_data (item);
-      return NULL;
-    }
-  }
-
-  return handle;
-}
-
-/**
- * @brief Get valve handle.
- */
-static void *
-nns_get_valve_handle (pipeline_info_s * pipe_info, const gchar * element_name)
-{
-  const nns_element_type_e etype = NNS_ELEMENT_TYPE_VALVE;
-  ml_pipeline_valve_h handle;
-  ml_pipeline_h pipe;
-  int status;
-
-  g_assert (pipe_info);
-  pipe = pipe_info->pipeline_handle;
-
-  handle = (ml_pipeline_valve_h) nns_get_element_handle (pipe_info,
-      element_name, etype);
-  if (handle == NULL) {
-    /* get valve handle and register to table */
-    status = ml_pipeline_valve_get_handle (pipe, element_name, &handle);
-    if (status != ML_ERROR_NONE) {
-      nns_loge ("Failed to get valve %s.", element_name);
-      return NULL;
-    }
-
-    element_data_s *item = g_new0 (element_data_s, 1);
-    if (item == NULL) {
-      nns_loge ("Failed to allocate memory for valve handle data.");
-      ml_pipeline_valve_release_handle (handle);
-      return NULL;
-    }
-
-    item->name = g_strdup (element_name);
-    item->type = etype;
-    item->handle = handle;
-    item->pipe_info = pipe_info;
-
-    if (!nns_add_element_data (pipe_info, element_name, item)) {
-      nns_loge ("Failed to add valve %s.", element_name);
-      nns_free_element_data (item);
-      return NULL;
-    }
-  }
-
-  return handle;
-}
-
-/**
- * @brief Get video sink element data in the pipeline.
- */
-static element_data_s *
-nns_get_video_sink_data (pipeline_info_s * pipe_info,
-    const gchar * element_name)
-{
-  const nns_element_type_e etype = NNS_ELEMENT_TYPE_VIDEO_SINK;
-  ml_pipeline_h pipe;
-  element_data_s *item;
-  int status;
-
-  g_assert (pipe_info);
-  pipe = pipe_info->pipeline_handle;
-
-  item = nns_get_element_data (pipe_info, element_name);
-  if (item == NULL) {
-    ml_pipeline_element_h handle;
-    GstElement *vsink;
-
-    /* get video sink handle and register to table */
-    status = ml_pipeline_element_get_handle (pipe, element_name, &handle);
-    if (status != ML_ERROR_NONE) {
-      nns_loge ("Failed to get the handle of %s.", element_name);
-      return NULL;
-    }
-
-    vsink = ((ml_pipeline_common_elem *) handle)->element->element;
-
-    if (!GST_IS_VIDEO_OVERLAY (vsink)) {
-      nns_loge ("Given element %s cannot set the window on video sink.",
-          element_name);
-      ml_pipeline_element_release_handle (handle);
-      return NULL;
-    }
-
-    item = g_new0 (element_data_s, 1);
-    item->name = g_strdup (element_name);
-    item->type = etype;
-    item->handle = handle;
-    item->pipe_info = pipe_info;
-
-    if (!nns_add_element_data (pipe_info, element_name, item)) {
-      nns_loge ("Failed to add video sink %s.", element_name);
-      nns_free_element_data (item);
-      return NULL;
-    }
-  }
-
-  return item;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jlong
-nns_native_pipe_construct (JNIEnv * env, jobject thiz, jstring description,
-    jboolean add_state_cb)
-{
-  pipeline_info_s *pipe_info = NULL;
-  pipeline_priv_data_s *priv;
-  ml_pipeline_h pipe;
-  int status;
-  const char *pipeline = (*env)->GetStringUTFChars (env, description, NULL);
-
-  pipe_info = nns_construct_pipe_info (env, thiz, NULL, NNS_PIPE_TYPE_PIPELINE);
-  if (pipe_info == NULL) {
-    nns_loge ("Failed to create pipe info.");
-    goto done;
-  }
-
-  priv = g_new0 (pipeline_priv_data_s, 1);
-  priv->mid_state_cb =
-      (*env)->GetMethodID (env, pipe_info->cls, "stateChanged", "(I)V");
-  priv->mid_sink_cb =
-      (*env)->GetMethodID (env, pipe_info->cls, "newDataReceived",
-      "(Ljava/lang/String;L" NNS_CLS_TDATA ";)V");
-
-  nns_set_priv_data (pipe_info, priv, nns_pipeline_priv_free);
-
-  if (add_state_cb)
-    status = ml_pipeline_construct (pipeline, nns_pipeline_state_cb, pipe_info,
-        &pipe);
-  else
-    status = ml_pipeline_construct (pipeline, NULL, NULL, &pipe);
-
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to create the pipeline.");
-    nns_destroy_pipe_info (pipe_info, env);
-    pipe_info = NULL;
-  } else {
-    pipe_info->pipeline_handle = pipe;
-  }
-
-done:
-  (*env)->ReleaseStringUTFChars (env, description, pipeline);
-  return CAST_TO_LONG (pipe_info);
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static void
-nns_native_pipe_destroy (JNIEnv * env, jobject thiz, jlong handle)
-{
-  pipeline_info_s *pipe_info = NULL;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  nns_destroy_pipe_info (pipe_info, env);
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_start (JNIEnv * env, jobject thiz, jlong handle)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_h pipe;
-  int status;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  pipe = pipe_info->pipeline_handle;
-
-  status = ml_pipeline_start (pipe);
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to start the pipeline.");
-    return JNI_FALSE;
-  }
-
-  return JNI_TRUE;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_stop (JNIEnv * env, jobject thiz, jlong handle)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_h pipe;
-  int status;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  pipe = pipe_info->pipeline_handle;
-
-  status = ml_pipeline_stop (pipe);
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to stop the pipeline.");
-    return JNI_FALSE;
-  }
-
-  return JNI_TRUE;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jint
-nns_native_pipe_get_state (JNIEnv * env, jobject thiz, jlong handle)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_h pipe;
-  ml_pipeline_state_e state;
-  int status;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  pipe = pipe_info->pipeline_handle;
-
-  status = ml_pipeline_get_state (pipe, &state);
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to get the pipeline state.");
-    state = ML_PIPELINE_STATE_UNKNOWN;
-  }
-
-  return (jint) state;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_input_data (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name, jobject in)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_src_h src;
-  ml_tensors_data_h in_data = NULL;
-  int status;
-  jboolean res = JNI_FALSE;
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  src = (ml_pipeline_src_h) nns_get_src_handle (pipe_info, element_name);
-  if (src == NULL) {
-    goto done;
-  }
-
-  if (!nns_parse_tensors_data (pipe_info, env, in, FALSE, &in_data, NULL)) {
-    nns_loge ("Failed to parse input data.");
-    goto done;
-  }
-
-  status = ml_pipeline_src_input_data (src, in_data,
-      ML_PIPELINE_BUF_POLICY_DO_NOT_FREE);
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to input tensors data to source node %s.", element_name);
-    goto done;
-  }
-
-  res = JNI_TRUE;
-
-done:
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  /* do not free input tensors (direct access from object) */
-  g_free (in_data);
-  return res;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jobjectArray
-nns_native_pipe_get_switch_pads (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_switch_h node;
-  int status;
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-  char **pad_list = NULL;
-  guint i, total;
-  jobjectArray result = NULL;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  node = (ml_pipeline_switch_h) nns_get_switch_handle (pipe_info, element_name);
-  if (node == NULL) {
-    goto done;
-  }
-
-  status = ml_pipeline_switch_get_pad_list (node, &pad_list);
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to get the pad list of switch %s.", element_name);
-    goto done;
-  }
-
-  total = g_strv_length (pad_list);
-
-  /* set string array */
-  if (total > 0) {
-    jclass cls_string = (*env)->FindClass (env, "java/lang/String");
-
-    result = (*env)->NewObjectArray (env, total, cls_string, NULL);
-    if (result == NULL) {
-      nns_loge ("Failed to allocate string array.");
-      (*env)->DeleteLocalRef (env, cls_string);
-      goto done;
-    }
-
-    for (i = 0; i < total; i++) {
-      jstring pad = (*env)->NewStringUTF (env, pad_list[i]);
-
-      (*env)->SetObjectArrayElement (env, result, i, pad);
-      (*env)->DeleteLocalRef (env, pad);
-    }
-
-    (*env)->DeleteLocalRef (env, cls_string);
-  }
-
-done:
-  g_strfreev (pad_list);
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  return result;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_select_switch_pad (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name, jstring pad)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_switch_h node;
-  int status;
-  jboolean res = JNI_FALSE;
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-  const char *pad_name = (*env)->GetStringUTFChars (env, pad, NULL);
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  node = (ml_pipeline_switch_h) nns_get_switch_handle (pipe_info, element_name);
-  if (node == NULL) {
-    goto done;
-  }
-
-  status = ml_pipeline_switch_select (node, pad_name);
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to select switch pad %s.", pad_name);
-    goto done;
-  }
-
-  res = JNI_TRUE;
-
-done:
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  (*env)->ReleaseStringUTFChars (env, pad, pad_name);
-  return res;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_control_valve (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name, jboolean open)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_valve_h node;
-  int status;
-  jboolean res = JNI_FALSE;
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  node = (ml_pipeline_valve_h) nns_get_valve_handle (pipe_info, element_name);
-  if (node == NULL) {
-    goto done;
-  }
-
-  status = ml_pipeline_valve_set_open (node, (open == JNI_TRUE));
-  if (status != ML_ERROR_NONE) {
-    nns_loge ("Failed to control valve %s.", element_name);
-    goto done;
-  }
-
-  res = JNI_TRUE;
-
-done:
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  return res;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_add_sink_cb (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_sink_h sink;
-  jboolean res = JNI_FALSE;
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  sink = (ml_pipeline_sink_h) nns_get_sink_handle (pipe_info, element_name);
-  if (sink == NULL) {
-    goto done;
-  }
-
-  res = JNI_TRUE;
-
-done:
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  return res;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_remove_sink_cb (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name)
-{
-  pipeline_info_s *pipe_info = NULL;
-  ml_pipeline_sink_h sink;
-  jboolean res = JNI_FALSE;
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  /* get handle from table */
-  sink = (ml_pipeline_sink_h) nns_get_element_handle (pipe_info, element_name,
-      NNS_ELEMENT_TYPE_SINK);
-  if (sink) {
-    nns_remove_element_data (pipe_info, element_name);
-    res = JNI_TRUE;
-  }
-
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  return res;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_initialize_surface (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name, jobject surface)
-{
-  pipeline_info_s *pipe_info;
-  element_data_s *edata;
-  jboolean res = JNI_FALSE;
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  edata = nns_get_video_sink_data (pipe_info, element_name);
-  if (edata) {
-    ANativeWindow *native_win;
-    GstElement *vsink;
-    pipeline_video_sink_priv_data_s *priv;
-    gboolean set_window = TRUE;
-
-    native_win = ANativeWindow_fromSurface (env, surface);
-    vsink = ((ml_pipeline_common_elem *) edata->handle)->element->element;
-    priv = (pipeline_video_sink_priv_data_s *) edata->priv_data;
-
-    if (priv == NULL) {
-      edata->priv_data = priv = g_new0 (pipeline_video_sink_priv_data_s, 1);
-      edata->priv_destroy_func = nns_pipeline_video_sink_priv_free;
-    }
-
-    if (priv->window) {
-      if (priv->window == native_win) {
-        set_window = FALSE;
-
-        gst_video_overlay_expose (GST_VIDEO_OVERLAY (vsink));
-        release_native_window (native_win);
-      } else {
-        /**
-         * Video sink may not change new window directly when calling set-window function.
-         * Keep old window handle to prevent invalid handle case in video sink.
-         */
-        release_native_window (priv->old_window);
-        priv->old_window = priv->window;
-        priv->window = NULL;
-      }
-    }
-
-    /* set new native window */
-    if (set_window) {
-      priv->window = native_win;
-      gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (vsink),
-          (guintptr) native_win);
-    }
-
-    res = JNI_TRUE;
-  }
-
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  return res;
-}
-
-/**
- * @brief Native method for pipeline API.
- */
-static jboolean
-nns_native_pipe_finalize_surface (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name)
-{
-  pipeline_info_s *pipe_info;
-  element_data_s *edata;
-  jboolean res = JNI_FALSE;
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  edata = nns_get_video_sink_data (pipe_info, element_name);
-  if (edata) {
-    GstElement *vsink;
-    pipeline_video_sink_priv_data_s *priv;
-
-    vsink = ((ml_pipeline_common_elem *) edata->handle)->element->element;
-    priv = (pipeline_video_sink_priv_data_s *) edata->priv_data;
-
-    gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (vsink),
-        (guintptr) NULL);
-    if (priv) {
-      release_native_window (priv->old_window);
-      priv->old_window = priv->window;
-      priv->window = NULL;
-    }
-
-    res = JNI_TRUE;
-  }
-
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  return res;
-}
-
-/**
- * @brief Native method to check the element registration.
- */
-static jboolean
-nns_native_check_element_availability (JNIEnv * env, jclass clazz, jstring name)
-{
-  const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
-  jboolean res = ml_element_is_available (element_name) ? JNI_TRUE : JNI_FALSE;
-
-  (*env)->ReleaseStringUTFChars (env, name, element_name);
-  return res;
-}
-
-/**
- * @brief List of implemented native methods for Pipeline class.
- */
-static JNINativeMethod native_methods_pipeline[] = {
-  {"nativeCheckElementAvailability", "(Ljava/lang/String;)Z",
-      (void *) nns_native_check_element_availability},
-  {"nativeConstruct", "(Ljava/lang/String;Z)J",
-      (void *) nns_native_pipe_construct},
-  {"nativeDestroy", "(J)V", (void *) nns_native_pipe_destroy},
-  {"nativeStart", "(J)Z", (void *) nns_native_pipe_start},
-  {"nativeStop", "(J)Z", (void *) nns_native_pipe_stop},
-  {"nativeGetState", "(J)I", (void *) nns_native_pipe_get_state},
-  {"nativeInputData", "(JLjava/lang/String;L" NNS_CLS_TDATA ";)Z",
-      (void *) nns_native_pipe_input_data},
-  {"nativeGetSwitchPads", "(JLjava/lang/String;)[Ljava/lang/String;",
-      (void *) nns_native_pipe_get_switch_pads},
-  {"nativeSelectSwitchPad", "(JLjava/lang/String;Ljava/lang/String;)Z",
-      (void *) nns_native_pipe_select_switch_pad},
-  {"nativeControlValve", "(JLjava/lang/String;Z)Z",
-      (void *) nns_native_pipe_control_valve},
-  {"nativeAddSinkCallback", "(JLjava/lang/String;)Z",
-      (void *) nns_native_pipe_add_sink_cb},
-  {"nativeRemoveSinkCallback", "(JLjava/lang/String;)Z",
-      (void *) nns_native_pipe_remove_sink_cb},
-  {"nativeInitializeSurface", "(JLjava/lang/String;Ljava/lang/Object;)Z",
-      (void *) nns_native_pipe_initialize_surface},
-  {"nativeFinalizeSurface", "(JLjava/lang/String;)Z",
-      (void *) nns_native_pipe_finalize_surface}
-};
-
-/**
- * @brief Register native methods for Pipeline class.
- */
-gboolean
-nns_native_pipe_register_natives (JNIEnv * env)
-{
-  jclass klass = (*env)->FindClass (env, NNS_CLS_PIPELINE);
-
-  if (klass) {
-    if ((*env)->RegisterNatives (env, klass, native_methods_pipeline,
-            G_N_ELEMENTS (native_methods_pipeline))) {
-      nns_loge ("Failed to register native methods for Pipeline class.");
-      return FALSE;
-    }
-  }
-
-  return TRUE;
-}
diff --git a/api/android/api/src/main/jni/nnstreamer-native-singleshot.c b/api/android/api/src/main/jni/nnstreamer-native-singleshot.c
deleted file mode 100644 (file)
index c752767..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/**
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-native-singleshot.c
- * @date       10 July 2019
- * @brief      Native code for NNStreamer API
- * @author     Jaeyun Jung <jy1210.jung@samsung.com>
- * @bug                No known bugs except for NYI items
- */
-
-#include "nnstreamer-native.h"
-
-/**
- * @brief Private data for SingleShot class.
- */
-typedef struct
-{
-  ml_tensors_info_h out_info;
-  jobject out_info_obj;
-} singleshot_priv_data_s;
-
-/**
- * @brief Release private data in pipeline info.
- */
-static void
-nns_singleshot_priv_free (gpointer data, JNIEnv * env)
-{
-  singleshot_priv_data_s *priv = (singleshot_priv_data_s *) data;
-
-  ml_tensors_info_destroy (priv->out_info);
-  if (priv->out_info_obj)
-    (*env)->DeleteGlobalRef (env, priv->out_info_obj);
-
-  g_free (priv);
-}
-
-/**
- * @brief Update output info in private data.
- */
-static gboolean
-nns_singleshot_priv_set_info (pipeline_info_s * pipe_info, JNIEnv * env)
-{
-  ml_single_h single;
-  singleshot_priv_data_s *priv;
-  ml_tensors_info_h out_info;
-  jobject obj_info = NULL;
-
-  single = pipe_info->pipeline_handle;
-  priv = (singleshot_priv_data_s *) pipe_info->priv_data;
-
-  if (ml_single_get_output_info (single, &out_info) != ML_ERROR_NONE) {
-    nns_loge ("Failed to get output info.");
-    return FALSE;
-  }
-
-  if (!ml_tensors_info_is_equal (out_info, priv->out_info)) {
-    if (!nns_convert_tensors_info (pipe_info, env, out_info, &obj_info)) {
-      nns_loge ("Failed to convert output info.");
-      ml_tensors_info_destroy (out_info);
-      return FALSE;
-    }
-
-    ml_tensors_info_destroy (priv->out_info);
-    priv->out_info = out_info;
-
-    if (priv->out_info_obj)
-      (*env)->DeleteGlobalRef (env, priv->out_info_obj);
-    priv->out_info_obj = (*env)->NewGlobalRef (env, obj_info);
-    (*env)->DeleteLocalRef (env, obj_info);
-  }
-
-  return TRUE;
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static jlong
-nns_native_single_open (JNIEnv * env, jobject thiz,
-    jobjectArray models, jobject in, jobject out, jint fw_type, jstring option)
-{
-  pipeline_info_s *pipe_info = NULL;
-  singleshot_priv_data_s *priv;
-  ml_single_h single = NULL;
-  ml_single_preset info = { 0, };
-  gboolean opened = FALSE;
-
-  pipe_info = nns_construct_pipe_info (env, thiz, NULL, NNS_PIPE_TYPE_SINGLE);
-  if (pipe_info == NULL) {
-    nns_loge ("Failed to create pipe info.");
-    goto done;
-  }
-
-  /* parse in/out tensors information */
-  if (in) {
-    if (!nns_parse_tensors_info (pipe_info, env, in, &info.input_info)) {
-      nns_loge ("Failed to parse input tensor.");
-      goto done;
-    }
-  }
-
-  if (out) {
-    if (!nns_parse_tensors_info (pipe_info, env, out, &info.output_info)) {
-      nns_loge ("Failed to parse output tensor.");
-      goto done;
-    }
-  }
-
-  /* nnfw type and hw resource */
-  if (!nns_get_nnfw_type (fw_type, &info.nnfw)) {
-    nns_loge ("Failed, unsupported framework (%d).", fw_type);
-    goto done;
-  }
-
-  info.hw = ML_NNFW_HW_ANY;
-
-  /* parse models */
-  if (models) {
-    GString *model_str;
-    jsize i, models_count;
-
-    model_str = g_string_new (NULL);
-    models_count = (*env)->GetArrayLength (env, models);
-
-    for (i = 0; i < models_count; i++) {
-      jstring model = (jstring) (*env)->GetObjectArrayElement (env, models, i);
-      const char *model_path = (*env)->GetStringUTFChars (env, model, NULL);
-
-      g_string_append (model_str, model_path);
-      if (i < models_count - 1) {
-        g_string_append (model_str, ",");
-      }
-
-      (*env)->ReleaseStringUTFChars (env, model, model_path);
-      (*env)->DeleteLocalRef (env, model);
-    }
-
-    info.models = g_string_free (model_str, FALSE);
-  } else {
-    nns_loge ("Failed to get model file.");
-    goto done;
-  }
-
-  /* parse option string */
-  if (option) {
-    const char *option_str = (*env)->GetStringUTFChars (env, option, NULL);
-
-    info.custom_option = g_strdup (option_str);
-    (*env)->ReleaseStringUTFChars (env, option, option_str);
-  }
-
-  if (ml_single_open_custom (&single, &info) != ML_ERROR_NONE) {
-    nns_loge ("Failed to create the pipeline.");
-    goto done;
-  }
-
-  pipe_info->pipeline_handle = single;
-
-  /* set private date */
-  priv = g_new0 (singleshot_priv_data_s, 1);
-  ml_tensors_info_create (&priv->out_info);
-  nns_set_priv_data (pipe_info, priv, nns_singleshot_priv_free);
-
-  if (!nns_singleshot_priv_set_info (pipe_info, env)) {
-    nns_loge ("Failed to set the metadata.");
-    goto done;
-  }
-
-  opened = TRUE;
-
-done:
-  ml_tensors_info_destroy (info.input_info);
-  ml_tensors_info_destroy (info.output_info);
-  g_free (info.models);
-  g_free (info.custom_option);
-
-  if (!opened) {
-    nns_destroy_pipe_info (pipe_info, env);
-    pipe_info = NULL;
-  }
-
-  return CAST_TO_LONG (pipe_info);
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static void
-nns_native_single_close (JNIEnv * env, jobject thiz, jlong handle)
-{
-  pipeline_info_s *pipe_info;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-
-  nns_destroy_pipe_info (pipe_info, env);
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static jobject
-nns_native_single_invoke (JNIEnv * env, jobject thiz, jlong handle, jobject in)
-{
-  pipeline_info_s *pipe_info;
-  singleshot_priv_data_s *priv;
-  ml_single_h single;
-  ml_tensors_data_h in_data, out_data;
-  jobject result = NULL;
-  gboolean failed = FALSE;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  priv = (singleshot_priv_data_s *) pipe_info->priv_data;
-  single = pipe_info->pipeline_handle;
-  in_data = out_data = NULL;
-
-  if (!nns_parse_tensors_data (pipe_info, env, in, FALSE, &in_data, NULL)) {
-    nns_loge ("Failed to parse input tensors data.");
-    failed = TRUE;
-    goto done;
-  }
-
-  /* create output object and get the direct buffer address */
-  if (!nns_create_tensors_data_object (pipe_info, env, priv->out_info_obj, &result) ||
-      !nns_parse_tensors_data (pipe_info, env, result, FALSE, &out_data, NULL)) {
-    nns_loge ("Failed to create output tensors object.");
-    failed = TRUE;
-    goto done;
-  }
-
-  if (ml_single_invoke_fast (single, in_data, out_data) != ML_ERROR_NONE) {
-    nns_loge ("Failed to invoke the model.");
-    failed = TRUE;
-    goto done;
-  }
-
-done:
-  if (failed) {
-    if (result) {
-      (*env)->DeleteLocalRef (env, result);
-      result = NULL;
-    }
-  }
-
-  /* do not free input/output tensors (direct access from object) */
-  g_free (in_data);
-  g_free (out_data);
-  return result;
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static jobject
-nns_native_single_get_input_info (JNIEnv * env, jobject thiz, jlong handle)
-{
-  pipeline_info_s *pipe_info;
-  ml_single_h single;
-  ml_tensors_info_h info;
-  jobject result = NULL;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  single = pipe_info->pipeline_handle;
-
-  if (ml_single_get_input_info (single, &info) != ML_ERROR_NONE) {
-    nns_loge ("Failed to get input info.");
-    goto done;
-  }
-
-  if (!nns_convert_tensors_info (pipe_info, env, info, &result)) {
-    nns_loge ("Failed to convert input info.");
-    result = NULL;
-  }
-
-done:
-  ml_tensors_info_destroy (info);
-  return result;
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static jobject
-nns_native_single_get_output_info (JNIEnv * env, jobject thiz, jlong handle)
-{
-  pipeline_info_s *pipe_info;
-  ml_single_h single;
-  ml_tensors_info_h info;
-  jobject result = NULL;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  single = pipe_info->pipeline_handle;
-
-  if (ml_single_get_output_info (single, &info) != ML_ERROR_NONE) {
-    nns_loge ("Failed to get output info.");
-    goto done;
-  }
-
-  if (!nns_convert_tensors_info (pipe_info, env, info, &result)) {
-    nns_loge ("Failed to convert output info.");
-    result = NULL;
-  }
-
-done:
-  ml_tensors_info_destroy (info);
-  return result;
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static jboolean
-nns_native_single_set_prop (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name, jstring value)
-{
-  pipeline_info_s *pipe_info;
-  ml_single_h single;
-  jboolean ret = JNI_FALSE;
-
-  const char *prop_name = (*env)->GetStringUTFChars (env, name, NULL);
-  const char *prop_value = (*env)->GetStringUTFChars (env, value, NULL);
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  single = pipe_info->pipeline_handle;
-
-  /* update info when changing the tensors information */
-  if (ml_single_set_property (single, prop_name, prop_value) == ML_ERROR_NONE &&
-      nns_singleshot_priv_set_info (pipe_info, env)) {
-    ret = JNI_TRUE;
-  } else {
-    nns_loge ("Failed to set the property (%s:%s).", prop_name, prop_value);
-  }
-
-  (*env)->ReleaseStringUTFChars (env, name, prop_name);
-  (*env)->ReleaseStringUTFChars (env, name, prop_value);
-  return ret;
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static jstring
-nns_native_single_get_prop (JNIEnv * env, jobject thiz, jlong handle,
-    jstring name)
-{
-  pipeline_info_s *pipe_info;
-  ml_single_h single;
-
-  const char *prop_name = (*env)->GetStringUTFChars (env, name, NULL);
-  char *prop_value = NULL;
-  jstring value = NULL;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  single = pipe_info->pipeline_handle;
-
-  if (ml_single_get_property (single, prop_name, &prop_value) == ML_ERROR_NONE) {
-    if (!prop_value) {
-      /* null string means error in java, return empty string. */
-      prop_value = g_strdup ("");
-    }
-
-    value = (*env)->NewStringUTF (env, prop_value);
-    g_free (prop_value);
-  } else {
-    nns_loge ("Failed to get the property (%s).", prop_name);
-  }
-
-  (*env)->ReleaseStringUTFChars (env, name, prop_name);
-  return value;
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static jboolean
-nns_native_single_set_timeout (JNIEnv * env, jobject thiz, jlong handle,
-    jint timeout)
-{
-  pipeline_info_s *pipe_info;
-  ml_single_h single;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  single = pipe_info->pipeline_handle;
-
-  if (ml_single_set_timeout (single, (unsigned int) timeout) != ML_ERROR_NONE) {
-    nns_loge ("Failed to set the timeout.");
-    return JNI_FALSE;
-  }
-
-  nns_logi ("Successfully set the timeout, %d milliseconds.", timeout);
-  return JNI_TRUE;
-}
-
-/**
- * @brief Native method for single-shot API.
- */
-static jboolean
-nns_native_single_set_input_info (JNIEnv * env, jobject thiz, jlong handle,
-    jobject in)
-{
-  pipeline_info_s *pipe_info;
-  ml_single_h single;
-  ml_tensors_info_h in_info = NULL;
-  jboolean ret = JNI_FALSE;
-
-  pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
-  single = pipe_info->pipeline_handle;
-
-  if (!nns_parse_tensors_info (pipe_info, env, in, &in_info)) {
-    nns_loge ("Failed to parse input tensor.");
-    goto done;
-  }
-
-  if (ml_single_set_input_info (single, in_info) == ML_ERROR_NONE &&
-      nns_singleshot_priv_set_info (pipe_info, env)) {
-    ret = JNI_TRUE;
-  } else {
-    nns_loge ("Failed to set input info.");
-  }
-
-done:
-  ml_tensors_info_destroy (in_info);
-  return ret;
-}
-
-/**
- * @brief List of implemented native methods for SingleShot class.
- */
-static JNINativeMethod native_methods_singleshot[] = {
-  {"nativeOpen", "([Ljava/lang/String;L" NNS_CLS_TINFO ";"
-        "L" NNS_CLS_TINFO ";ILjava/lang/String;)J",
-      (void *) nns_native_single_open},
-  {"nativeClose", "(J)V", (void *) nns_native_single_close},
-  {"nativeInvoke", "(JL" NNS_CLS_TDATA ";)L" NNS_CLS_TDATA ";",
-      (void *) nns_native_single_invoke},
-  {"nativeGetInputInfo", "(J)L" NNS_CLS_TINFO ";",
-      (void *) nns_native_single_get_input_info},
-  {"nativeGetOutputInfo", "(J)L" NNS_CLS_TINFO ";",
-      (void *) nns_native_single_get_output_info},
-  {"nativeSetProperty", "(JLjava/lang/String;Ljava/lang/String;)Z",
-      (void *) nns_native_single_set_prop},
-  {"nativeGetProperty", "(JLjava/lang/String;)Ljava/lang/String;",
-      (void *) nns_native_single_get_prop},
-  {"nativeSetTimeout", "(JI)Z", (void *) nns_native_single_set_timeout},
-  {"nativeSetInputInfo", "(JL" NNS_CLS_TINFO ";)Z",
-      (void *) nns_native_single_set_input_info}
-};
-
-/**
- * @brief Register native methods for SingleShot class.
- */
-gboolean
-nns_native_single_register_natives (JNIEnv * env)
-{
-  jclass klass = (*env)->FindClass (env, NNS_CLS_SINGLE);
-
-  if (klass) {
-    if ((*env)->RegisterNatives (env, klass, native_methods_singleshot,
-            G_N_ELEMENTS (native_methods_singleshot))) {
-      nns_loge ("Failed to register native methods for SingleShot class.");
-      return FALSE;
-    }
-  }
-
-  return TRUE;
-}
diff --git a/api/android/api/src/main/jni/nnstreamer-native.h b/api/android/api/src/main/jni/nnstreamer-native.h
deleted file mode 100644 (file)
index 407e5cf..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * NNStreamer Android API
- * Copyright (C) 2019 Samsung Electronics Co., Ltd.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-native.h
- * @date       10 July 2019
- * @brief      Native code for NNStreamer API
- * @author     Jaeyun Jung <jy1210.jung@samsung.com>
- * @bug                No known bugs except for NYI items
- */
-
-#ifndef __NNSTREAMER_ANDROID_NATIVE_H__
-#define __NNSTREAMER_ANDROID_NATIVE_H__
-
-#include <jni.h>
-#include <android/native_window.h>
-#include <android/native_window_jni.h>
-
-#include <gst/gst.h>
-#include <gst/video/video.h>
-
-#include "nnstreamer.h"
-#include "nnstreamer-single.h"
-#include "nnstreamer-capi-private.h"
-#include "nnstreamer_log.h"
-#include "nnstreamer_plugin_api.h"
-#include "nnstreamer_plugin_api_filter.h"
-
-#if GLIB_SIZEOF_VOID_P == 8
-#define CAST_TO_LONG(p) (jlong)(p)
-#define CAST_TO_TYPE(l,type) (type)(l)
-#else
-#define CAST_TO_LONG(p) (jlong)(jint)(p)
-#define CAST_TO_TYPE(l,type) (type)(jint)(l)
-#endif
-
-/**
- * @brief NNStreamer package name.
- */
-#define NNS_PKG "org/nnsuite/nnstreamer"
-#define NNS_CLS_TDATA NNS_PKG "/TensorsData"
-#define NNS_CLS_TINFO NNS_PKG "/TensorsInfo"
-#define NNS_CLS_PIPELINE NNS_PKG "/Pipeline"
-#define NNS_CLS_SINGLE NNS_PKG "/SingleShot"
-#define NNS_CLS_CUSTOM_FILTER NNS_PKG "/CustomFilter"
-#define NNS_CLS_NNSTREAMER NNS_PKG "/NNStreamer"
-
-/**
- * @brief Callback to destroy private data in pipe info.
- */
-typedef void (*nns_priv_destroy)(gpointer data, JNIEnv * env);
-
-/**
- * @brief Pipeline type in native pipe info.
- */
-typedef enum
-{
-  NNS_PIPE_TYPE_PIPELINE = 0,
-  NNS_PIPE_TYPE_SINGLE,
-  NNS_PIPE_TYPE_CUSTOM,
-
-  NNS_PIPE_TYPE_UNKNOWN
-} nns_pipe_type_e;
-
-/**
- * @brief Element type in native pipe info.
- */
-typedef enum
-{
-  NNS_ELEMENT_TYPE_SRC = 0,
-  NNS_ELEMENT_TYPE_SINK,
-  NNS_ELEMENT_TYPE_VALVE,
-  NNS_ELEMENT_TYPE_SWITCH,
-  NNS_ELEMENT_TYPE_VIDEO_SINK,
-
-  NNS_ELEMENT_TYPE_UNKNOWN
-} nns_element_type_e;
-
-/**
- * @brief Struct for TensorsData class info.
- */
-typedef struct
-{
-  jclass cls;
-  jmethodID mid_init;
-  jmethodID mid_alloc;
-  jmethodID mid_get_array;
-  jmethodID mid_get_info;
-} data_class_info_s;
-
-/**
- * @brief Struct for TensorsInfo class info.
- */
-typedef struct
-{
-  jclass cls;
-  jmethodID mid_init;
-  jmethodID mid_add_info;
-  jmethodID mid_get_array;
-
-  jclass cls_info;
-  jfieldID fid_info_name;
-  jfieldID fid_info_type;
-  jfieldID fid_info_dim;
-} info_class_info_s;
-
-/**
- * @brief Struct for constructed pipeline.
- */
-typedef struct
-{
-  nns_pipe_type_e pipeline_type;
-  gpointer pipeline_handle;
-  GHashTable *element_handles;
-  GMutex lock;
-
-  JavaVM *jvm;
-  jint version;
-  pthread_key_t jni_env;
-
-  jobject instance;
-  jclass cls;
-  data_class_info_s data_cls_info;
-  info_class_info_s info_cls_info;
-
-  gpointer priv_data;
-  nns_priv_destroy priv_destroy_func;
-} pipeline_info_s;
-
-/**
- * @brief Struct for element data in pipeline.
- */
-typedef struct
-{
-  gchar *name;
-  nns_element_type_e type;
-  gpointer handle;
-  pipeline_info_s *pipe_info;
-
-  gpointer priv_data;
-  nns_priv_destroy priv_destroy_func;
-} element_data_s;
-
-/**
- * @brief Get JNI environment.
- */
-extern JNIEnv *
-nns_get_jni_env (pipeline_info_s * pipe_info);
-
-/**
- * @brief Free element handle pointer.
- */
-extern void
-nns_free_element_data (gpointer data);
-
-/**
- * @brief Construct pipeline info.
- */
-extern gpointer
-nns_construct_pipe_info (JNIEnv * env, jobject thiz, gpointer handle, nns_pipe_type_e type);
-
-/**
- * @brief Destroy pipeline info.
- */
-extern void
-nns_destroy_pipe_info (pipeline_info_s * pipe_info, JNIEnv * env);
-
-/**
- * @brief Set private data in pipeline info.
- */
-extern void
-nns_set_priv_data (pipeline_info_s * pipe_info, gpointer data, nns_priv_destroy destroy_func);
-
-/**
- * @brief Get element data of given name.
- */
-extern element_data_s *
-nns_get_element_data (pipeline_info_s * pipe_info, const gchar * name);
-
-/**
- * @brief Get element handle of given name and type.
- */
-extern gpointer
-nns_get_element_handle (pipeline_info_s * pipe_info, const gchar * name, const nns_element_type_e type);
-
-/**
- * @brief Remove element data of given name.
- */
-extern gboolean
-nns_remove_element_data (pipeline_info_s * pipe_info, const gchar * name);
-
-/**
- * @brief Add new element data of given name.
- */
-extern gboolean
-nns_add_element_data (pipeline_info_s * pipe_info, const gchar * name, element_data_s * item);
-
-/**
- * @brief Create new data object with given tensors info. Caller should unref the result object.
- */
-extern gboolean
-nns_create_tensors_data_object (pipeline_info_s * pipe_info, JNIEnv * env, jobject obj_info, jobject * result);
-
-/**
- * @brief Convert tensors data to TensorsData object.
- */
-extern gboolean
-nns_convert_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env, ml_tensors_data_h data_h, jobject obj_info, jobject * result);
-
-/**
- * @brief Parse tensors data from TensorsData object.
- */
-extern gboolean
-nns_parse_tensors_data (pipeline_info_s * pipe_info, JNIEnv * env, jobject obj_data, gboolean clone, ml_tensors_data_h * data_h, ml_tensors_info_h * info_h);
-
-/**
- * @brief Convert tensors info to TensorsInfo object.
- */
-extern gboolean
-nns_convert_tensors_info (pipeline_info_s * pipe_info, JNIEnv * env, ml_tensors_info_h info_h, jobject * result);
-
-/**
- * @brief Parse tensors info from TensorsInfo object.
- */
-extern gboolean
-nns_parse_tensors_info (pipeline_info_s * pipe_info, JNIEnv * env, jobject obj_info, ml_tensors_info_h * info_h);
-
-/**
- * @brief Get NNFW from integer value.
- */
-extern gboolean
-nns_get_nnfw_type (jint fw_type, ml_nnfw_type_e * nnfw);
-
-/**
- * @brief Register native methods for SingleShot class.
- */
-extern gboolean
-nns_native_single_register_natives (JNIEnv * env);
-
-#if !defined (NNS_SINGLE_ONLY)
-/**
- * @brief Register native methods for Pipeline class.
- */
-extern gboolean
-nns_native_pipe_register_natives (JNIEnv * env);
-
-/**
- * @brief Register native methods for CustomFilter class.
- */
-extern gboolean
-nns_native_custom_register_natives (JNIEnv * env);
-#endif
-
-#endif /* __NNSTREAMER_ANDROID_NATIVE_H__ */
diff --git a/api/android/build-android-lib.sh b/api/android/build-android-lib.sh
deleted file mode 100644 (file)
index 62843a2..0000000
+++ /dev/null
@@ -1,599 +0,0 @@
-#!/usr/bin/env bash
-
-##
-## SPDX-License-Identifier: LGPL-2.1-only
-##
-# @file  build-android-lib.sh
-# @brief A script to build NNStreamer API library for Android
-#
-# The following comments that start with '##@@' are for the generation of usage messages.
-##@@ Build script for Android NNStreamer API Library
-##@@  - Before running this script, below variables must be set.
-##@@  - ANDROID_SDK_ROOT: Android SDK
-##@@  - ANDROID_NDK_ROOT: Android NDK
-##@@  - GSTREAMER_ROOT_ANDROID: GStreamer prebuilt libraries for Android
-##@@  - NNSTREAMER_ROOT: The source root directory of NNStreamer
-##@@ 
-##@@ usage: build-android-lib.sh [OPTIONS]
-##@@ 
-##@@ basic options:
-##@@   --help
-##@@       display this help and exit
-##@@   --build-type=(all|lite|single|internal)
-##@@       'all'      : default
-##@@       'lite'     : build with GStreamer core plugins
-##@@       'single'   : no plugins, single-shot only
-##@@       'internal' : no plugins except for enable single-shot only, enable NNFW only
-##@@   --target_abi=(armeabi-v7a|arm64-v8a)
-##@@       'arm64-v8a' is the default Android ABI
-##@@   --run_test=(yes|no)
-##@@       'yes'      : run instrumentation test after build procedure is done
-##@@       'no'       : [default]
-##@@   --nnstreamer_dir=(the_source_root_of_nnstreamer)
-##@@       This option overrides the NNSTREAMER_ROOT variable
-##@@ 
-##@@ options for tensor filter sub-plugins:
-##@@   --enable_snap=(yes|no)
-##@@       'yes'      : build with sub-plugin for SNAP
-##@@                    This option requires 1n additional variable, 'SNAP_DIRECTORY',
-##@@                    which indicates the SNAP SDK interface's absolute path.
-##@@       'no'       : [default]
-##@@   --enable_nnfw=(yes|no)
-##@@       'yes'      : [default]
-##@@       'no'       : build without the sub-plugin for NNFW
-##@@   --enable_snpe=(yes|no)
-##@@       'yes'      : build with sub-plugin for SNPE
-##@@       'no'       : [default]
-##@@   --enable_pytorch=(yes(:(1.8.0))?|no)
-##@@       'yes'      : build with sub-plugin for PyTorch. You can optionally specify the version of
-##@@                    PyTorch to use by appending ':version' [1.8.0 is the default].
-##@@       'no'       : [default] build without the sub-plugin for PyTorch
-##@@   --enable_tflite=(yes(:(1.9|1.13.1|1.15.2|2.3.0))?|no)
-##@@       'yes'      : [default] you can optionally specify the version of tensorflow-lite to use
-##@@                    by appending ':version' [1.13.1 is the default].
-##@@       'no'       : build without the sub-plugin for tensorflow-lite
-##@@ 
-##@@ options for tensor decoder sub-plugins:
-##@@   --enable_decoder_flatbuf=(yes|no)
-##@@       'yes'      : [default]
-##@@       'no'       : build without the sub-plugin for FlatBuffers
-##@@ 
-##@@ For example, to build library with core plugins for arm64-v8a
-##@@  ./build-android-lib.sh --api_option=lite --target_abi=arm64-v8a
-
-set -e
-
-# API build option
-# 'all' : default
-# 'lite' : with GStreamer core plugins
-# 'single' : no plugins, single-shot only
-# 'internal' : no plugins, single-shot only, enable NNFW only
-build_type="all"
-
-nnstreamer_api_option="all"
-include_assets="no"
-
-# Set target ABI ('armeabi-v7a', 'arm64-v8a')
-target_abi="arm64-v8a"
-
-# Run instrumentation test after build procedure is done
-run_test="no"
-
-# Variables to release library (GROUP:ARTIFACT:VERSION)
-release_bintray="no"
-
-# Enable SNAP
-enable_snap="no"
-
-# Enable NNFW
-enable_nnfw="yes"
-
-# Enable SNPE
-enable_snpe="no"
-
-# Enable PyTorch
-enable_pytorch="no"
-
-# Set PyTorch version (available: 1.8.0 (unstable))
-pytorch_ver="1.8.0"
-pytorch_vers_support="1.8.0"
-
-# Enable tensorflow-lite
-enable_tflite="yes"
-
-# Enable the flatbuffer decoder by default
-enable_decoder_flatbuf="yes"
-decoder_flatbuf_ver="1.12.0"
-
-# Set tensorflow-lite version (available: 1.9.0 / 1.13.1 / 1.15.2 / 2.3.0)
-tf_lite_ver="1.13.1"
-tf_lite_vers_support="1.9.0 1.13.1 1.15.2 2.3.0"
-
-# Set NNFW version (https://github.com/Samsung/ONE/releases)
-nnfw_ver="1.12.0"
-enable_nnfw_ext="no"
-
-# Find '--help' in the given arguments
-arg_help="--help"
-for arg in "$@"; do
-    if [[ $arg == $arg_help ]]; then
-        sed -ne 's/^##@@ \(.*\)/\1/p' $0 && exit 1
-    fi
-done
-
-# Parse args
-for arg in "$@"; do
-    case $arg in
-        --build_type=*)
-            build_type=${arg#*=}
-            ;;
-        --target_abi=*)
-            target_abi=${arg#*=}
-            if [ $target_abi != "armeabi-v7a" ] && [ $target_abi != "arm64-v8a" ]; then
-                echo "Unknown target ABI." && exit 1
-            fi
-            ;;
-        --release=*)
-            release_bintray=${arg#*=}
-            ;;
-        --release_version=*)
-            release_version=${arg#*=}
-            ;;
-        --bintray_user_name=*)
-            bintray_user_name=${arg#*=}
-            ;;
-        --bintray_user_key=*)
-            bintray_user_key=${arg#*=}
-            ;;
-        --run_test=*)
-            run_test=${arg#*=}
-            ;;
-        --nnstreamer_dir=*)
-            nnstreamer_dir=${arg#*=}
-            ;;
-        --result_dir=*)
-            result_dir=${arg#*=}
-            ;;
-        --gstreamer_dir=*)
-            gstreamer_dir=${arg#*=}
-            ;;
-        --android_sdk_dir=*)
-            android_sdk_dir=${arg#*=}
-            ;;
-        --android_ndk_dir=*)
-            android_ndk_dir=${arg#*=}
-            ;;
-        --enable_snap=*)
-            enable_snap=${arg#*=}
-            ;;
-        --enable_nnfw=*)
-            enable_nnfw=${arg#*=}
-            ;;
-        --enable_nnfw_ext=*)
-            enable_nnfw_ext=${arg#*=}
-            ;;
-        --enable_snpe=*)
-            enable_snpe=${arg#*=}
-            ;;
-        --enable_pytorch=*)
-            IFS=':' read -ra enable_pytorch_args <<< "${arg#*=}"
-            is_valid_pytorch_version=0
-            enable_pytorch=${enable_pytorch_args[0]}
-            if [[ ${enable_pytorch} == "yes" ]]; then
-                if [[ ${enable_pytorch_args[1]} == "" ]]; then
-                    break
-                fi
-                for ver in ${pytorch_vers_support}; do
-                    if [[ ${ver} == ${enable_pytorch_args[1]} ]]; then
-                        is_valid_pytorch_version=1
-                        pytorch_ver=${ver}
-                        break
-                    fi
-                done
-                if [[ ${is_valid_pytorch_version} == 0 ]]; then
-                    printf "'%s' is not a supported version of PyTorch." "${enable_pytorch_args[1]}"
-                    printf "The default version, '%s', will be used.\n"  "${pytorch_ver}"
-                fi
-            fi
-            ;;
-        --enable_tflite=*)
-            IFS=':' read -ra enable_tflite_args <<< "${arg#*=}"
-            is_valid_tflite_version=0
-            enable_tflite=${enable_tflite_args[0]}
-            if [[ ${enable_tflite} == "yes" ]]; then
-                if [[ ${enable_tflite_args[1]} == "" ]]; then
-                    break
-                fi
-                for ver in ${tf_lite_vers_support}; do
-                    if [[ ${ver} == ${enable_tflite_args[1]} ]]; then
-                        is_valid_tflite_version=1
-                        tf_lite_ver=${ver}
-                        break
-                    fi
-                done
-                if [[ ${is_valid_tflite_version} == 0 ]]; then
-                    printf "'%s' is not a supported version of TensorFlow Lite." "${enable_tflite_args[1]}"
-                    printf "The default version, '%s', will be used.\n"  "${tf_lite_ver}"
-                fi
-            fi
-            ;;
-        --enable_decoder_flatbuf=*)
-            enable_decoder_flatbuf=${arg#*=}
-            ;;
-    esac
-done
-
-# Check build type
-if [[ $build_type == "single" ]]; then
-    nnstreamer_api_option="single"
-elif [[ $build_type == "lite" ]]; then
-    nnstreamer_api_option="lite"
-elif [[ $build_type == "internal" ]]; then
-    nnstreamer_api_option="single"
-
-    enable_snap="no"
-    enable_nnfw="yes"
-    enable_nnfw_ext="yes"
-    enable_snpe="no"
-    enable_pytorch="no"
-    enable_tflite="no"
-
-    target_abi="arm64-v8a"
-elif [[ $build_type != "all" ]]; then
-    echo "Failed, unknown build type $build_type." && exit 1
-fi
-
-if [[ $enable_snap == "yes" ]]; then
-    [ -z "$SNAP_DIRECTORY" ] && echo "Need to set SNAP_DIRECTORY, to build sub-plugin for SNAP." && exit 1
-    [ $target_abi != "arm64-v8a" ] && echo "Set target ABI arm64-v8a to build sub-plugin for SNAP." && exit 1
-
-    echo "Build with SNAP: $SNAP_DIRECTORY"
-fi
-
-if [[ $enable_nnfw == "yes" ]]; then
-    [ $target_abi != "arm64-v8a" ] && echo "Set target ABI arm64-v8a to build sub-plugin for NNFW." && exit 1
-
-    echo "Build with NNFW $nnfw_ver"
-
-    if [[ $enable_nnfw_ext == "yes" ]]; then
-        [ -z "$NNFW_DIRECTORY" ] && echo "Need to set NNFW_DIRECTORY, to get NNFW-ext library." && exit 1
-    fi
-fi
-
-if [[ $enable_snpe == "yes" ]]; then
-    [ $enable_snap == "yes" ] && echo "DO NOT enable SNAP and SNPE both. The app would fail to use DSP or NPU runtime." && exit 1
-    [ -z "$SNPE_DIRECTORY" ] && echo "Need to set SNPE_DIRECTORY, to build sub-plugin for SNPE." && exit 1
-    [ $target_abi != "arm64-v8a" ] && echo "Set target ABI arm64-v8a to build sub-plugin for SNPE." && exit 1
-
-    echo "Build with SNPE: $SNPE_DIRECTORY"
-fi
-
-if [[ $enable_pytorch == "yes" ]]; then
-    echo "Build with PyTorch $pytorch_ver"
-fi
-
-if [[ $enable_tflite == "yes" ]]; then
-    echo "Build with tensorflow-lite $tf_lite_ver"
-fi
-
-if [[ $release_bintray == "yes" ]]; then
-    [ -z "$release_version" ] && echo "Set release version." && exit 1
-    [ -z "$bintray_user_name" ] || [ -z "$bintray_user_key" ] && echo "Set user info to release." && exit 1
-
-    echo "Release version: $release_version user: $bintray_user_name"
-fi
-
-if [[ $enable_decoder_flatbuf == "yes" ]]; then
-    echo "Build with flatbuffers v$decoder_flatbuf_ver for the decoder sub-plugin"
-fi
-
-# Set library name
-nnstreamer_lib_name="nnstreamer"
-
-if [[ $build_type != "all" ]]; then
-    nnstreamer_lib_name="$nnstreamer_lib_name-$build_type"
-fi
-
-echo "NNStreamer library name: $nnstreamer_lib_name"
-
-# Android SDK (Set your own path)
-if [[ -z "$android_sdk_dir" ]]; then
-    [ -z "$ANDROID_SDK_ROOT" ] && echo "Need to set ANDROID_SDK_ROOT." && exit 1
-    android_sdk_dir=$ANDROID_SDK_ROOT
-fi
-
-if [[ -z "$android_ndk_dir" ]]; then
-    [ -z "$ANDROID_NDK_ROOT" ] && echo "Need to set ANDROID_NDK_ROOT." && exit 1
-    android_ndk_dir=$ANDROID_NDK_ROOT
-fi
-
-echo "Android SDK: $android_sdk_dir"
-echo "Android NDK: $android_ndk_dir"
-
-echo "Patching NDK source"
-# See: https://github.com/nnstreamer/nnstreamer/issues/2899
-
-sed -z -i "s|struct AMediaCodecOnAsyncNotifyCallback {\n      AMediaCodecOnAsyncInputAvailable  onAsyncInputAvailable;\n      AMediaCodecOnAsyncOutputAvailable onAsyncOutputAvailable;\n      AMediaCodecOnAsyncFormatChanged   onAsyncFormatChanged;\n      AMediaCodecOnAsyncError           onAsyncError;\n};|typedef struct AMediaCodecOnAsyncNotifyCallback {\n      AMediaCodecOnAsyncInputAvailable  onAsyncInputAvailable;\n      AMediaCodecOnAsyncOutputAvailable onAsyncOutputAvailable;\n      AMediaCodecOnAsyncFormatChanged   onAsyncFormatChanged;\n      AMediaCodecOnAsyncError           onAsyncError;\n} AMediaCodecOnAsyncNotifyCallback;|" $android_ndk_dir/toolchains/llvm/prebuilt/*/sysroot/usr/include/media/NdkMediaCodec.h
-
-# GStreamer prebuilt libraries for Android
-# Download from https://gstreamer.freedesktop.org/data/pkg/android/
-if [[ -z "$gstreamer_dir" ]]; then
-    [ -z "$GSTREAMER_ROOT_ANDROID" ] && echo "Need to set GSTREAMER_ROOT_ANDROID." && exit 1
-    gstreamer_dir=$GSTREAMER_ROOT_ANDROID
-fi
-
-echo "GStreamer binaries: $gstreamer_dir"
-
-# NNStreamer root directory
-if [[ -z "$nnstreamer_dir" ]]; then
-    [ -z "$NNSTREAMER_ROOT" ] && echo "Need to set NNSTREAMER_ROOT." && exit 1
-    nnstreamer_dir=$NNSTREAMER_ROOT
-fi
-
-echo "NNStreamer root directory: $nnstreamer_dir"
-
-# Build result directory
-if [[ -z "$result_dir" ]]; then
-    result_dir=$nnstreamer_dir/android_lib
-fi
-
-mkdir -p $result_dir
-
-echo "Start to build NNStreamer library for Android (build $build_type)"
-pushd $nnstreamer_dir
-
-# Make directory to build NNStreamer library
-build_dir=build_android_$build_type
-mkdir -p $build_dir
-
-# Copy the files (native and java to build Android library) to build directory
-cp -r ./api/android/* ./$build_dir
-
-# Get the prebuilt libraries and build-script
-mkdir -p $build_dir/external
-
-svn --force export https://github.com/nnstreamer/nnstreamer-android-resource/trunk/android_api ./$build_dir
-
-# @todo We need another mechanism for downloading third-party/external softwares
-rm -f ./$build_dir/external/*.tar.gz ./$build_dir/external/*.tar.xz
-if [[ $enable_tflite == "yes" ]]; then
-    wget --directory-prefix=./$build_dir/external https://raw.githubusercontent.com/nnstreamer/nnstreamer-android-resource/master/external/tensorflow-lite-$tf_lite_ver.tar.xz
-fi
-
-if [[ $enable_nnfw == "yes" ]]; then
-    wget --directory-prefix=./$build_dir/external https://github.com/Samsung/ONE/releases/download/$nnfw_ver/onert-$nnfw_ver-android-aarch64.tar.gz
-    wget --directory-prefix=./$build_dir/external https://github.com/Samsung/ONE/releases/download/$nnfw_ver/onert-devel-$nnfw_ver.tar.gz
-
-    # You should get ONE-EXT release and copy it into NNFW_DIRECTORY.
-    if [[ $enable_nnfw_ext == "yes" ]]; then
-        cp $NNFW_DIRECTORY/onert-ext-$nnfw_ver-android-aarch64.tar.gz ./$build_dir/external
-    fi
-fi
-
-if [[ $enable_pytorch == "yes" ]]; then
-    wget --directory-prefix=./$build_dir/external https://raw.githubusercontent.com/nnstreamer/nnstreamer-android-resource/master/external/pytorch-$pytorch_ver.tar.xz
-fi
-
-pushd ./$build_dir
-
-# Update target ABI
-sed -i "s|abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'|abiFilters '$target_abi'|" api/build.gradle
-
-# 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 NNStreamer, GStreamer and Android SDK
-sed -i "s|nnstreamerRoot=nnstreamer-path|nnstreamerRoot=$nnstreamer_dir|" gradle.properties
-sed -i "s|gstAndroidRoot=gstreamer-path|gstAndroidRoot=$gstreamer_dir|" gradle.properties
-sed -i "s|ndk.dir=ndk-path|ndk.dir=$android_ndk_dir|" local.properties
-sed -i "s|sdk.dir=sdk-path|sdk.dir=$android_sdk_dir|" local.properties
-
-# Update SNAP option
-if [[ $enable_snap == "yes" ]]; then
-    sed -i "s|ENABLE_SNAP := false|ENABLE_SNAP := true|" api/src/main/jni/Android-nnstreamer-prebuilt.mk
-    sed -i "s|ENABLE_SNAP := false|ENABLE_SNAP := true|" api/src/main/jni/Android.mk
-
-    mkdir -p api/src/main/jni/snap/include api/src/main/jni/snap/lib
-    cp $SNAP_DIRECTORY/*.h api/src/main/jni/snap/include
-    cp $SNAP_DIRECTORY/*.so api/src/main/jni/snap/lib
-fi
-
-# Update NNFW option
-if [[ $enable_nnfw == "yes" ]]; then
-    sed -i "s|ENABLE_NNFW := false|ENABLE_NNFW := true|" api/src/main/jni/Android-nnstreamer-prebuilt.mk
-    sed -i "s|ENABLE_NNFW := false|ENABLE_NNFW := true|" api/src/main/jni/Android.mk
-    sed -i "$ a NNFW_EXT_LIBRARY_PATH=src/main/jni/nnfw/ext" gradle.properties
-
-    mkdir -p external/nnfw
-    tar -zxf external/onert-$nnfw_ver-android-aarch64.tar.gz -C external/nnfw
-    tar -zxf external/onert-devel-$nnfw_ver.tar.gz -C external/nnfw
-
-    if [[ $enable_nnfw_ext == "yes" ]]; then
-        tar -zxf external/onert-ext-$nnfw_ver-android-aarch64.tar.gz -C external/nnfw
-    fi
-
-    # Remove duplicated, unnecessary files (c++shared and tensorflow-lite)
-    rm -f external/nnfw/lib/libc++_shared.so
-    rm -f external/nnfw/lib/libtensorflowlite_jni.so
-    rm -f external/nnfw/lib/libneuralnetworks.so
-
-    mkdir -p api/src/main/jni/nnfw/include api/src/main/jni/nnfw/lib
-    mkdir -p api/src/main/jni/nnfw/ext/arm64-v8a
-    mv external/nnfw/include/* api/src/main/jni/nnfw/include
-    mv external/nnfw/lib/libnnfw-dev.so api/src/main/jni/nnfw/lib
-    mv external/nnfw/lib/* api/src/main/jni/nnfw/ext/arm64-v8a
-fi
-
-# Update SNPE option
-if [[ $enable_snpe == "yes" ]]; then
-    sed -i "s|ENABLE_SNPE := false|ENABLE_SNPE := true|" api/src/main/jni/Android-nnstreamer-prebuilt.mk
-    sed -i "s|ENABLE_SNPE := false|ENABLE_SNPE := true|" api/src/main/jni/Android.mk
-    sed -i "$ a SNPE_EXT_LIBRARY_PATH=src/main/jni/snpe/lib/ext" gradle.properties
-
-    mkdir -p api/src/main/jni/snpe/lib/ext/arm64-v8a
-    cp -r $SNPE_DIRECTORY/include api/src/main/jni/snpe
-    cp $SNPE_DIRECTORY/lib/aarch64-android-clang6.0/libSNPE.so api/src/main/jni/snpe/lib
-
-    # Copy external so files for SNPE
-    cp $SNPE_DIRECTORY/lib/aarch64-android-clang6.0/lib*dsp*.so api/src/main/jni/snpe/lib/ext/arm64-v8a
-    cp $SNPE_DIRECTORY/lib/aarch64-android-clang6.0/libhta.so api/src/main/jni/snpe/lib/ext/arm64-v8a
-    cp $SNPE_DIRECTORY/lib/dsp/libsnpe*.so api/src/main/jni/snpe/lib/ext/arm64-v8a
-fi
-
-# Update PyTorch option
-if [[ $enable_pytorch == "yes" ]]; then
-    sed -i "s|ENABLE_PYTORCH := false|ENABLE_PYTORCH := true|" api/src/main/jni/Android.mk
-    sed -i "s|PYTORCH_VERSION := 1.8.0|PYTORCH_VERSION := $pytorch_ver|" api/src/main/jni/Android-pytorch.mk
-    tar -xJf ./external/pytorch-$pytorch_ver.tar.xz -C ./api/src/main/jni
-fi
-
-# Update tf-lite option
-if [[ $enable_tflite == "yes" ]]; then
-    sed -i "s|ENABLE_TF_LITE := false|ENABLE_TF_LITE := true|" api/src/main/jni/Android-nnstreamer-prebuilt.mk
-    sed -i "s|ENABLE_TF_LITE := false|ENABLE_TF_LITE := true|" api/src/main/jni/Android.mk
-    sed -i "s|TFLITE_VERSION := 1.13.1|TFLITE_VERSION := $tf_lite_ver|" api/src/main/jni/Android-tensorflow-lite.mk
-    tar -xJf ./external/tensorflow-lite-$tf_lite_ver.tar.xz -C ./api/src/main/jni
-fi
-
-
-if [[ $enable_decoder_flatbuf == "yes" ]]; then
-    sed -i "s|ENABLE_DECODER_FLATBUF := false|ENABLE_DECODER_FLATBUF := true|" api/src/main/jni/Android.mk
-    sed -i "s|FLATBUF_VER := @FLATBUF_VER@|FLATBUF_VER := ${decoder_flatbuf_ver}|" api/src/main/jni/Android-dec-flatbuf.mk
-    wget --directory-prefix=./external https://raw.githubusercontent.com/nnstreamer/nnstreamer-android-resource/master/external/flatbuffers-${decoder_flatbuf_ver}.tar.xz
-    tar -xJf ./external/flatbuffers-${decoder_flatbuf_ver}.tar.xz -C ./api/src/main/jni
-fi
-
-# Add dependency for release
-if [[ $release_bintray == "yes" ]]; then
-    sed -i "s|// add dependency (bintray)|classpath 'com.novoda:bintray-release:0.9.1'|" build.gradle
-
-    sed -i "s|// add plugin (bintray)|apply plugin: 'com.novoda.bintray-release'\n\
-\n\
-publish {\n\
-    userOrg = 'nnsuite'\n\
-    repoName = 'nnstreamer'\n\
-    groupId = 'org.nnsuite'\n\
-    artifactId = '$nnstreamer_lib_name'\n\
-    publishVersion = '$release_version'\n\
-    desc = 'NNStreamer API for Android'\n\
-    website = 'https://github.com/nnstreamer/nnstreamer'\n\
-    issueTracker = 'https://github.com/nnstreamer/nnstreamer/issues'\n\
-    repository = 'https://github.com/nnstreamer/nnstreamer.git'\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."
-
-# Build Android library.
-chmod +x gradlew
-sh ./gradlew api:build
-
-# Check if build procedure is done.
-nnstreamer_android_api_lib=./api/build/outputs/aar/api-release.aar
-
-android_lib_build_res=1
-if [[ -e "$nnstreamer_android_api_lib" ]]; then
-    today=$(date "+%Y-%m-%d")
-    android_lib_build_res=0
-
-    # Prepare native libraries and header files for C-API
-    unzip $nnstreamer_android_api_lib -d aar_extracted
-
-    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
-
-    # native libraries and mk files
-    cp -r aar_extracted/jni/* main/jni/nnstreamer/lib
-    cp api/src/main/jni/*-prebuilt.mk main/jni
-
-    # header for C-API
-    cp $nnstreamer_dir/api/capi/include/nnstreamer.h main/jni/nnstreamer/include
-    cp $nnstreamer_dir/api/capi/include/nnstreamer-single.h main/jni/nnstreamer/include
-    cp $nnstreamer_dir/api/capi/include/ml-api-common.h main/jni/nnstreamer/include
-    cp $nnstreamer_dir/api/capi/include/platform/tizen_error.h main/jni/nnstreamer/include
-
-    # header for plugin
-    if [[ $nnstreamer_api_option != "single" ]]; then
-        cp $nnstreamer_dir/gst/nnstreamer/include/*.h main/jni/nnstreamer/include
-        cp $nnstreamer_dir/gst/nnstreamer/include/*.hh main/jni/nnstreamer/include
-        cp $nnstreamer_dir/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
-
-    # Prepare static libs in ndk build
-    mkdir -p ndk_static/debug
-    mkdir -p ndk_static/release
-
-    cp api/build/intermediates/ndkBuild/debug/obj/local/$target_abi/*.a ndk_static/debug
-    cp api/build/intermediates/ndkBuild/release/obj/local/$target_abi/*.a ndk_static/release
-
-    nnstreamer_static_libs="$nnstreamer_lib_name-static-libs-$today.zip"
-    zip -r $nnstreamer_static_libs ndk_static
-
-    rm -rf aar_extracted main ndk_static
-
-    # Upload to jcenter
-    if [[ $release_bintray == "yes" ]]; then
-        echo "Upload NNStreamer library to Bintray."
-        sh ./gradlew api:bintrayUpload -PbintrayUser=$bintray_user_name -PbintrayKey=$bintray_user_key -PdryRun=false
-    fi
-
-    # Run instrumentation test
-    if [[ $run_test == "yes" ]]; then
-        echo "Run instrumentation test."
-        sh ./gradlew api:connectedCheck
-
-        test_result="$nnstreamer_lib_name-test-$today.zip"
-        zip -r $test_result api/build/reports
-        cp $test_result $result_dir
-
-        test_summary=$(sed -n "/<div class=\"percent\">/p" api/build/reports/androidTests/connected/index.html)
-        if [[ $test_summary != "<div class=\"percent\">100%</div>" ]]; then
-            echo "Instrumentation test failed."
-            android_lib_build_res=1
-        fi
-    fi
-
-    # Copy build result
-    if [[ $android_lib_build_res == 0 ]]; then
-        echo "Build procedure is done, copy NNStreamer library to $result_dir directory."
-
-        cp $nnstreamer_android_api_lib $result_dir/$nnstreamer_lib_name-$today.aar
-        cp $nnstreamer_native_files $result_dir
-        cp $nnstreamer_static_libs $result_dir
-    fi
-else
-    echo "Failed to build NNStreamer library."
-fi
-
-popd
-
-# Remove build directory
-rm -rf $build_dir
-
-popd
-cd ${nnstreamer_dir} && find -name nnstreamer_version.h -delete
-
-# exit with success/failure status
-exit $android_lib_build_res
diff --git a/api/android/build.gradle b/api/android/build.gradle
deleted file mode 100644 (file)
index 169e6ee..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
-    repositories {
-        jcenter()
-        google()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:3.3.1'
-        // add dependency (bintray)
-
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-        google()
-    }
-}
-
-task clean(type: Delete) {
-    delete rootProject.buildDir
-}
diff --git a/api/android/settings.gradle b/api/android/settings.gradle
deleted file mode 100644 (file)
index 5f53697..0000000
+++ /dev/null
@@ -1 +0,0 @@
-include ':api'
diff --git a/api/capi/capi-ml-common.pc.in b/api/capi/capi-ml-common.pc.in
deleted file mode 100644 (file)
index 26146ce..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# Package Information for pkg-config
-
-prefix=@PREFIX@
-exec_prefix=@PREFIX@
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDE_INSTALL_DIR@
-
-Name: tizen-api-ml-common
-Description: ml-common API for Tizen
-Version: @VERSION@
-Requires:
-Libs: -L${libdir}
-Cflags: -I${includedir}/nnstreamer
diff --git a/api/capi/capi-nnstreamer.pc.in b/api/capi/capi-nnstreamer.pc.in
deleted file mode 100644 (file)
index a0e0c0e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# Package Information for pkg-config
-
-prefix=@PREFIX@
-exec_prefix=@PREFIX@
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDE_INSTALL_DIR@
-
-Name: tizen-api-nnstreamer
-Description: NNStreamer API for Tizen
-Version: @VERSION@
-Requires: capi-ml-common
-Libs: -L${libdir} -lcapi-nnstreamer
-Cflags: -I${includedir}/nnstreamer
diff --git a/api/capi/doc/images/capi_nnstreamer_pipeline_state.jpg b/api/capi/doc/images/capi_nnstreamer_pipeline_state.jpg
deleted file mode 100644 (file)
index feaa1a1..0000000
Binary files a/api/capi/doc/images/capi_nnstreamer_pipeline_state.jpg and /dev/null differ
diff --git a/api/capi/doc/nnstreamer_doc.h b/api/capi/doc/nnstreamer_doc.h
deleted file mode 100644 (file)
index 78e2961..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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_doc.h
- * @date 06 March 2019
- * @brief Tizen C-API Declaration for Tizen SDK
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#ifndef __TIZEN_MACHINELEARNING_NNSTREAMER_DOC_H__
-#define __TIZEN_MACHINELEARNING_NNSTREAMER_DOC_H__
-
-/**
- * @ingroup  CAPI_ML_FRAMEWORK
- * @defgroup CAPI_ML_NNSTREAMER_PIPELINE_MODULE Pipeline
- * @addtogroup CAPI_ML_NNSTREAMER_PIPELINE_MODULE
- * @brief The NNStreamer function provides interfaces to create and execute stream pipelines with neural networks and sensors.
- * @section CAPI_ML_NNSTREAMER_PIPELINE_HEADER Required Header
- *   \#include <nnstreamer/nnstreamer.h>\n
- * @section CAPI_ML_NNSTREAMER_PIPELINE_OVERVIEW Overview
- * The NNStreamer function provides interfaces to create and execute stream pipelines with neural networks and sensors.
- *
- *  This function allows the following operations with NNStreamer:
- * - Create a stream pipeline with NNStreamer plugins, GStreamer plugins, and sensor/camera/mic inputs.
- * - Interfaces to push data to the pipeline from the application.
- * - Interfaces to pull data from the pipeline to the application.
- * - Interfaces to start/stop/destroy the pipeline.
- * - Interfaces to control switches and valves in the pipeline.
- * - Utility functions to handle data from the pipeline.
- *
- *  Note that this function set is supposed to be thread-safe.
- *
- * @subsection CAPI_ML_NNSTREAMER_PIPELINE_STATE_DIAGRAM Pipeline State Diagram
- * @image html capi_nnstreamer_pipeline_state.jpg "Figure1. Pipeline State" width=12cm
- *
- * @section CAPI_ML_NNSTREAMER_PIPELINE_FEATURE Related Features
- * This function is related with the following features:\n
- *  - %http://tizen.org/feature/machine_learning\n
- *  - %http://tizen.org/feature/machine_learning.inference\n
- *
- * It is recommended to probe features in your application for reliability.\n
- * You can check if a device supports the related features for this function by using
- * @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of
- * your application.\n
- * To ensure your application is only running on the device with specific
- * features, please define the features in your manifest file using the manifest
- * editor in the SDK.\n
- * For example, your application accesses to the camera device,
- * then you have to add '%http://tizen.org/privilege/camera' into the manifest of your application.\n
- * More details on featuring your application can be found from
- * <a href="https://docs.tizen.org/application/tizen-studio/native-tools/manifest-text-editor#feature-element">
- *    <b>Feature Element</b>.
- * </a>
- */
-
-/**
- * @ingroup  CAPI_ML_FRAMEWORK
- * @defgroup CAPI_ML_NNSTREAMER_SINGLE_MODULE Single
- * @addtogroup CAPI_ML_NNSTREAMER_SINGLE_MODULE
- * @brief The NNStreamer Single API provides interfaces to invoke a neural network model with a single instance of input data.
- * @section CAPI_ML_NNSTREAMER_SINGLE_HEADER Required Header
- *   \#include <nnstreamer/nnstreamer-single.h>\n
- *
- * @section CAPI_ML_NNSTREAMER_SINGLE_OVERVIEW Overview
- * The NNStreamer Single API provides interfaces to invoke a neural network model with a single instance of input data.
- * This function is a syntactic sugar of NNStreamer Pipeline API with simplified features; thus, users are supposed to use NNStreamer Pipeline API directly if they want more advanced features.
- * The user is expected to preprocess the input data for the given neural network model.
- *
- * This function allows the following operations with NNStreamer:
- * - Open a machine learning model with various mechanisms.
- * - Close the model.
- * - Interfaces to enter a single instance of input data to the opened model.
- * - Utility functions to get the information of opened model.
- *
- * Note that this function set is supposed to be thread-safe.
- *
- * @section CAPI_ML_NNSTREAMER_SINGLE_FEATURE Related Features
- * This function is related with the following features:\n
- *  - %http://tizen.org/feature/machine_learning\n
- *  - %http://tizen.org/feature/machine_learning.inference\n
- *
- * It is recommended to probe features in your application for reliability.\n
- * You can check if a device supports the related features for this function by using
- * @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of
- * your application.\n
- * To ensure your application is only running on the device with specific
- * features, please define the features in your manifest file using the manifest
- * editor in the SDK.\n
- * For example, your application accesses to the camera device,
- * then you have to add '%http://tizen.org/privilege/camera' into the manifest of your application.\n
- * More details on featuring your application can be found from
- * <a href="https://docs.tizen.org/application/tizen-studio/native-tools/manifest-text-editor#feature-element">
- *    <b>Feature Element</b>.
- * </a>
- */
-
-
-#endif /* __TIZEN_MACHINELEARNING_NNSTREAMER_DOC_H__ */
diff --git a/api/capi/include/ml-api-common.h b/api/capi/include/ml-api-common.h
deleted file mode 100644 (file)
index da44108..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-only */
-/**
- * NNStreamer API / Tizen Machine-Learning API Common Header
- * Copyright (C) 2020 MyungJoo Ham <myungjoo.ham@samsung.com>
- */
-/**
- * @file    ml-api-common.h
- * @date    07 May 2020
- * @brief   ML-API Common Header
- * @see     https://github.com/nnstreamer/nnstreamer
- * @author  MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug     No known bugs except for NYI items
- *
- * @details
- *      More entries might be migrated from nnstreamer.h if
- *    other modules of Tizen-ML APIs use common data structures.
- */
-#ifndef __ML_API_COMMON_H__
-#define __ML_API_COMMON_H__
-
-#include <tizen_error.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-/**
- * @addtogroup CAPI_ML_FRAMEWORK
- * @{
- */
-
-/**
- * @brief Enumeration for the error codes of NNStreamer.
- * @since_tizen 5.5
- */
-typedef enum {
-  ML_ERROR_NONE                 = TIZEN_ERROR_NONE, /**< Success! */
-  ML_ERROR_INVALID_PARAMETER    = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
-  ML_ERROR_STREAMS_PIPE         = TIZEN_ERROR_STREAMS_PIPE, /**< Cannot create or access the pipeline. */
-  ML_ERROR_TRY_AGAIN            = TIZEN_ERROR_TRY_AGAIN, /**< The pipeline is not ready, yet (not negotiated, yet) */
-  ML_ERROR_UNKNOWN              = TIZEN_ERROR_UNKNOWN,  /**< Unknown error */
-  ML_ERROR_TIMED_OUT            = TIZEN_ERROR_TIMED_OUT,  /**< Time out */
-  ML_ERROR_NOT_SUPPORTED        = TIZEN_ERROR_NOT_SUPPORTED, /**< The feature is not supported */
-  ML_ERROR_PERMISSION_DENIED    = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
-  ML_ERROR_OUT_OF_MEMORY        = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory (Since 6.0) */
-} ml_error_e;
-
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __ML_API_COMMON_H__ */
diff --git a/api/capi/include/nnstreamer-capi-private.h b/api/capi/include/nnstreamer-capi-private.h
deleted file mode 100644 (file)
index d0fb46c..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-/**
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-capi-private.h
- * @date 07 March 2019
- * @brief NNStreamer/Pipeline(main) C-API Private Header.
- *        This file should NOT be exported to SDK or devel package.
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#ifndef __NNSTREAMER_CAPI_PRIVATE_H__
-#define __NNSTREAMER_CAPI_PRIVATE_H__
-
-#include <glib.h>
-#include <gst/gst.h>
-
-#include "nnstreamer.h"
-#include "nnstreamer-single.h"
-#include "tensor_typedef.h"
-#include "nnstreamer_log.h"
-
-/* Tizen ML feature */
-#if defined (__TIZEN__)
-#include "nnstreamer-tizen-internal.h"
-
-typedef enum
-{
-  NOT_CHECKED_YET = -1,
-  NOT_SUPPORTED = 0,
-  SUPPORTED = 1
-} feature_state_t;
-
-#if defined (__FEATURE_CHECK_SUPPORT__)
-#define check_feature_state() \
-  do { \
-    int feature_ret = ml_tizen_get_feature_enabled (); \
-    if (ML_ERROR_NONE != feature_ret) \
-      return feature_ret; \
-  } while (0);
-
-#define set_feature_state(...) ml_tizen_set_feature_state(__VA_ARGS__)
-#else
-#define check_feature_state()
-#define set_feature_state(...)
-#endif  /* __FEATURE_CHECK_SUPPORT__ */
-
-#if defined (__PRIVILEGE_CHECK_SUPPORT__)
-
-#define convert_tizen_element(...) ml_tizen_convert_element(__VA_ARGS__)
-
-#if (TIZENVERSION >= 5) && (TIZENVERSION < 9999)
-#define get_tizen_resource(...) ml_tizen_get_resource(__VA_ARGS__)
-#define release_tizen_resource(...) ml_tizen_release_resource(__VA_ARGS__)
-#define TIZEN5PLUS 1
-
-#elif (TIZENVERSION < 5)
-#define get_tizen_resource(...) (0)
-#define release_tizen_resource(...) do { } while (0)
-typedef void * mm_resource_manager_h;
-typedef enum { MM_RESOURCE_MANAGER_RES_TYPE_MAX } mm_resource_manager_res_type_e;
-#define TIZEN5PLUS 0
-
-#else
-#error Tizen version is not defined.
-#endif
-
-#else
-
-#define convert_tizen_element(...) ML_ERROR_NONE
-#define get_tizen_resource(...) ML_ERROR_NONE
-#define release_tizen_resource(...)
-#define TIZEN5PLUS 0
-
-#endif  /* __PRIVILEGE_CHECK_SUPPORT__ */
-
-#else
-#define check_feature_state()
-#define set_feature_state(...)
-#define convert_tizen_element(...) ML_ERROR_NONE
-#define get_tizen_resource(...) ML_ERROR_NONE
-#define release_tizen_resource(...)
-#define TIZEN5PLUS 0
-#endif  /* __TIZEN__ */
-
-#define EOS_MESSAGE_TIME_LIMIT 100
-#define WAIT_PAUSED_TIME_LIMIT 100
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * @brief Internal private representation of custom filter handle.
- */
-typedef struct {
-  char *name;
-  ml_tensors_info_h in_info;
-  ml_tensors_info_h out_info;
-  ml_custom_easy_invoke_cb cb;
-  void *pdata;
-} ml_custom_filter_s;
-
-/**
- * @brief Data structure for tensor information.
- * @since_tizen 5.5
- */
-typedef struct {
-  char *name;              /**< Name of each element in the tensor. */
-  ml_tensor_type_e type;   /**< Type of each element in the tensor. */
-  ml_tensor_dimension dimension;     /**< Dimension information. */
-} ml_tensor_info_s;
-
-/**
- * @brief Data structure for tensors information, which contains multiple tensors.
- * @since_tizen 5.5
- */
-typedef struct {
-  unsigned int num_tensors; /**< The number of tensors. */
-  ml_tensor_info_s info[ML_TENSOR_SIZE_LIMIT];  /**< The list of tensor info. */
-} ml_tensors_info_s;
-
-/**
- * @brief An instance of a single input or output frame.
- * @since_tizen 5.5
- */
-typedef struct {
-  void *tensor; /**< The instance of tensor data. */
-  size_t size; /**< The size of tensor. */
-} ml_tensor_data_s;
-
-/**
- * @brief An instance of input or output frames. #ml_tensors_info_h is the handle for tensors metadata.
- * @since_tizen 5.5
- */
-typedef struct {
-  unsigned int num_tensors; /**< The number of tensors. */
-  ml_tensor_data_s tensors[ML_TENSOR_SIZE_LIMIT]; /**< The list of tensor data. NULL for unused tensors. */
-  void *handle; /**< The handle which owns this buffer and will be used to de-alloc the data */
-} ml_tensors_data_s;
-
-/**
- * @brief Internal private representation of tensor_if custom conditon.
- * @since_tizen 6.5
- */
-typedef struct {
-  char *name;
-  ml_pipeline_if_custom_cb cb;
-  void *pdata;
-} ml_if_custom_s;
-
-/**
- * @brief Possible controls on elements of a pipeline.
- */
-typedef enum {
-  ML_PIPELINE_ELEMENT_UNKNOWN = 0x0,
-  ML_PIPELINE_ELEMENT_SINK = 0x1,
-  ML_PIPELINE_ELEMENT_APP_SRC = 0x2,
-  ML_PIPELINE_ELEMENT_APP_SINK = 0x3,
-  ML_PIPELINE_ELEMENT_VALVE = 0x4,
-  ML_PIPELINE_ELEMENT_SWITCH_INPUT = 0x8,
-  ML_PIPELINE_ELEMENT_SWITCH_OUTPUT = 0x9,
-  ML_PIPELINE_ELEMENT_COMMON = 0xB,
-} ml_pipeline_element_e;
-
-/**
- * @brief Internal private representation of pipeline handle.
- */
-typedef struct _ml_pipeline ml_pipeline;
-
-/**
- * @brief An element that may be controlled individually in a pipeline.
- */
-typedef struct _ml_pipeline_element {
-  GstElement *element; /**< The Sink/Src/Valve/Switch element */
-  ml_pipeline *pipe; /**< The main pipeline */
-  char *name;
-  ml_pipeline_element_e type;
-  GstPad *src;
-  GstPad *sink; /**< Unref this at destroy */
-  ml_tensors_info_s tensors_info;
-  size_t size;
-
-  GList *handles;
-  int maxid; /**< to allocate id for each handle */
-  gulong handle_id;
-
-  GMutex lock; /**< Lock for internal values */
-  gboolean is_media_stream;
-} ml_pipeline_element;
-
-/**
- * @brief Internal data structure for the pipeline state callback.
- */
-typedef struct {
-  ml_pipeline_state_cb cb; /**< Callback to notify the change of pipeline state */
-  void *user_data; /**< The user data passed when calling the state change callback */
-} pipeline_state_cb_s;
-
-/**
- * @brief Internal data structure for the resource.
- */
-typedef struct {
-  gchar *type; /**< resource type */
-  gpointer handle; /**< pointer to resource handle */
-} pipeline_resource_s;
-
-/**
- * @brief Internal private representation of pipeline handle.
- * @details This should not be exposed to applications
- */
-struct _ml_pipeline {
-  GstElement *element;            /**< The pipeline itself (GstPipeline) */
-  GstBus *bus;                    /**< The bus of the pipeline */
-  gulong signal_msg;              /**< The message signal (connected to bus) */
-  GMutex lock;                    /**< Lock for pipeline operations */
-  gboolean isEOS;                 /**< The pipeline is EOS state */
-  ml_pipeline_state_e pipe_state; /**< The state of pipeline */
-  GHashTable *namednodes;         /**< hash table of "element"s. */
-  GHashTable *resources;          /**< hash table of resources to construct the pipeline */
-  pipeline_state_cb_s state_cb;   /**< Callback to notify the change of pipeline state */
-};
-
-/**
- * @brief Internal private representation sink callback function for GstTensorSink and GstAppSink
- * @details This represents a single instance of callback registration. This should not be exposed to applications.
- */
-typedef struct {
-  ml_pipeline_sink_cb cb;
-  void *pdata;
-} callback_info_s;
-
-/**
- * @brief Internal private representation of common element handle (All GstElement except AppSink and TensorSink)
- * @details This represents a single instance of registration. This should not be exposed to applications.
- */
-typedef struct _ml_pipeline_common_elem {
-  ml_pipeline *pipe;
-  ml_pipeline_element *element;
-  guint32 id;
-  callback_info_s *callback_info;   /**< Callback function information. If element is not GstTensorSink or GstAppSink, then it should be NULL. */
-} ml_pipeline_common_elem;
-
-/**
- * @brief An information to create single-shot instance.
- */
-typedef struct {
-  ml_tensors_info_h input_info;  /**< The input tensors information. */
-  ml_tensors_info_h output_info; /**< The output tensors information. */
-  ml_nnfw_type_e nnfw;           /**< The neural network framework. */
-  ml_nnfw_hw_e hw;               /**< The type of hardware resource. */
-  char *models;                  /**< Comma separated neural network model files. */
-  char *custom_option;           /**< Custom option string for neural network framework. */
-} ml_single_preset;
-
-/**
- * @brief Opens an ML model with the custom options and returns the instance as a handle.
- * This is internal function to handle various options in public APIs.
- */
-int ml_single_open_custom (ml_single_h *single, ml_single_preset *info);
-
-/**
- * @brief Macro to check the availability of given NNFW.
- */
-#define ml_nnfw_is_available(f,h) ({bool a; (ml_check_nnfw_availability ((f), (h), &a) == ML_ERROR_NONE && a);})
-
-/**
- * @brief Macro to check the availability of given element.
- */
-#define ml_element_is_available(e) ({bool a; (ml_check_element_availability ((e), &a) == ML_ERROR_NONE && a);})
-
-/**
- * @brief Macro to check the tensors info is valid.
- */
-#define ml_tensors_info_is_valid(i) ({bool v; (ml_tensors_info_validate ((i), &v) == ML_ERROR_NONE && v);})
-
-/**
- * @brief Macro to compare the tensors info.
- */
-#define ml_tensors_info_is_equal(i1,i2) ({bool e; (ml_tensors_info_compare ((i1), (i2), &e) == ML_ERROR_NONE && e);})
-
-/**
- * @brief Gets the byte size of the given tensor info.
- */
-size_t ml_tensor_info_get_size (const ml_tensor_info_s *info);
-
-/**
- * @brief Initializes the tensors information with default value.
- * @since_tizen 5.5
- * @param[in] info The tensors info pointer to be initialized.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_initialize (ml_tensors_info_s *info);
-
-/**
- * @brief Compares the given tensors information.
- * @details If the function returns an error, @a equal is not changed.
- * @since_tizen 6.0
- * @param[in] info1 The handle of tensors information to be compared.
- * @param[in] info2 The handle of tensors information to be compared.
- * @param[out] equal @c true if given tensors information is equal, @c false if it's not equal.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_compare (const ml_tensors_info_h info1, const ml_tensors_info_h info2, bool *equal);
-
-/**
- * @brief Frees the tensors info pointer.
- * @since_tizen 5.5
- * @param[in] info The tensors info pointer to be freed.
- */
-void ml_tensors_info_free (ml_tensors_info_s *info);
-
-/**
- * @brief Allocates a tensors information handle from gst info.
- */
-int ml_tensors_info_create_from_gst (ml_tensors_info_h *ml_info, GstTensorsInfo *gst_info);
-
-/**
- * @brief Copies tensor metadata from gst tensors info.
- */
-void ml_tensors_info_copy_from_gst (ml_tensors_info_s *ml_info, const GstTensorsInfo *gst_info);
-
-/**
- * @brief Copies tensor metadata from ml tensors info.
- */
-void ml_tensors_info_copy_from_ml (GstTensorsInfo *gst_info, const ml_tensors_info_s *ml_info);
-
-/**
- * @brief Creates a tensor data frame without buffer with the given tensors information.
- * @details If @a info is null, this allocates data handle with empty tensor data.
- * @param[in] info The handle of tensors information for the allocation.
- * @param[out] data The handle of tensors data.
- * @return @c 0 on success. Otherwise a negative error value.
- */
-int ml_tensors_data_create_no_alloc (const ml_tensors_info_h info, ml_tensors_data_h *data);
-
-/**
- * @brief Creates a tensor data frame without allocating new buffer cloning the given tensors data.
- * @details If @a data_src is null, this returns error.
- * @param[in] data_src The handle of tensors data to be cloned.
- * @param[out] data The handle of tensors data.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_tensors_data_clone_no_alloc (const ml_tensors_data_s * data_src, ml_tensors_data_h * data);
-
-/**
- * @brief Initializes the GStreamer library. This is internal function.
- */
-int ml_initialize_gstreamer (void);
-
-/**
- * @brief Validates the nnfw model file.
- * @since_tizen 5.5
- * @param[in] model List of model file paths.
- * @param[in] num_models The number of model files. There are a few frameworks that require multiple model files for a single model.
- * @param[in/out] nnfw The type of NNFW.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_validate_model_file (const char * const *model, const unsigned int num_models, ml_nnfw_type_e * nnfw);
-
-/**
- * @brief Checks the availability of the plugin.
- */
-int ml_check_plugin_availability (const char *plugin_name, const char *element_name);
-
-/**
- * @brief Internal function to convert accelerator as tensor_filter property format.
- * @note returned value must be freed by the caller
- */
-char* ml_nnfw_to_str_prop (ml_nnfw_hw_e hw);
-
-/**
- * @brief Internal function to get the sub-plugin name.
- */
-const char* ml_get_nnfw_subplugin_name (ml_nnfw_type_e nnfw);
-
-/**
- * @brief Internal function to get the nnfw type.
- */
-ml_nnfw_type_e ml_get_nnfw_type_by_subplugin_name (const char *name);
-
-/**
- * @brief Gets the element of pipeline itself (GstElement).
- * @details With the returned reference, you can use GStreamer functions to handle the element in pipeline.
- *          Note that caller should release the returned reference using gst_object_unref().
- * @return The reference of pipeline itself. Null if the pipeline is not constructed or closed.
- */
-GstElement* ml_pipeline_get_gst_element (ml_pipeline_h pipe);
-
-int ml_single_destroy_notify (ml_single_h single, ml_tensors_data_s *data);
-
-#if defined (__TIZEN__)
-/**
- * @brief Checks whether machine_learning.inference feature is enabled or not.
- */
-int ml_tizen_get_feature_enabled (void);
-
-/**
- * @brief Set the feature status of machine_learning.inference.
- * This is only used for Unit test.
- */
-int ml_tizen_set_feature_state (int state);
-
-/**
- * @brief Releases the resource handle of Tizen.
- */
-void ml_tizen_release_resource (gpointer handle, const gchar * res_type);
-
-/**
- * @brief Gets the resource handle of Tizen.
- */
-int ml_tizen_get_resource (ml_pipeline_h pipe, const gchar * res_type);
-
-/**
- * @brief Converts predefined element for Tizen.
- */
-int ml_tizen_convert_element (ml_pipeline_h pipe, gchar ** result, gboolean is_internal);
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __NNSTREAMER_CAPI_PRIVATE_H__ */
diff --git a/api/capi/include/nnstreamer-single.h b/api/capi/include/nnstreamer-single.h
deleted file mode 100644 (file)
index 25ec39f..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-single.h
- * @date 29 March 2019
- * @brief NNStreamer single-shot invocation C-API Header.
- *        This allows to invoke a neural network model directly.
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- *
- * @details This is targeting Tizen 5.5 M2.
- */
-
-#ifndef __TIZEN_MACHINELEARNING_NNSTREAMER_SINGLE_H__
-#define __TIZEN_MACHINELEARNING_NNSTREAMER_SINGLE_H__
-
-#include <nnstreamer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-/**
- * @addtogroup CAPI_ML_NNSTREAMER_SINGLE_MODULE
- * @{
- */
-
-/**
- * @brief A handle of a single-shot instance.
- * @since_tizen 5.5
- */
-typedef void *ml_single_h;
-
-/*************
- * MAIN FUNC *
- *************/
-/**
- * @brief Opens an ML model and returns the instance as a handle.
- * @details Even if the model has flexible input data dimensions,
- *          input data frames of an instance of a model should share the same dimension.
- * @since_tizen 5.5
- * @remarks %http://tizen.org/privilege/mediastorage is needed if @a model is relevant to media storage.
- * @remarks %http://tizen.org/privilege/externalstorage is needed if @a model is relevant to external storage.
- * @param[out] single This is the model handle opened. Users are required to close
- *                   the given instance with ml_single_close().
- * @param[in] model This is the path to the neural network model file.
- * @param[in] input_info This is required if the given model has flexible input
- *                      dimension, where the input dimension MUST be given
- *                      before executing the model.
- *                      It is required by some custom filters of NNStreamer.
- *                      You may set NULL if it's not required.
- * @param[in] output_info This is required if the given model has flexible output dimension.
- * @param[in] nnfw The neural network framework used to open the given @a model.
- *                 Set #ML_NNFW_TYPE_ANY to let it auto-detect.
- * @param[in] hw Tell the corresponding @a nnfw to use a specific hardware.
- *               Set #ML_NNFW_HW_ANY if it does not matter.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_PERMISSION_DENIED The application does not have the privilege to access to the media storage or external storage.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE Failed to start the pipeline.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_single_open (ml_single_h *single, const char *model, const ml_tensors_info_h input_info, const ml_tensors_info_h output_info, ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw);
-
-/**
- * @brief Opens an ML model and returns the instance as a handle with custom options.
- * @details Even if the model has flexible input data dimensions,
- *          input data frames of an instance of a model should share the same dimension.
- * @since_tizen 6.5
- * @remarks %http://tizen.org/privilege/mediastorage is needed if @a model is relevant to media storage.
- * @remarks %http://tizen.org/privilege/externalstorage is needed if @a model is relevant to external storage.
- * @param[out] single This is the model handle opened. Users are required to close
- *                   the given instance with ml_single_close().
- * @param[in] model This is the path to the neural network model file.
- * @param[in] input_info This is required if the given model has flexible input
- *                      dimension, where the input dimension MUST be given
- *                      before executing the model.
- *                      It is required by some custom filters of NNStreamer.
- *                      You may set NULL if it's not required.
- * @param[in] output_info This is required if the given model has flexible output dimension.
- * @param[in] nnfw The neural network framework used to open the given @a model.
- *                 Set #ML_NNFW_TYPE_ANY to let it auto-detect.
- * @param[in] hw Tell the corresponding @a nnfw to use a specific hardware.
- *               Set #ML_NNFW_HW_ANY if it does not matter.
- * @param[in] custom_option Comma separated list of options.
- *                      Use this parameter to fine-tune and optimize specific neural network framework. (e.g. NumThreads:N to set the number of threads in TensorFlow-Lite)
- *                      You may set NULL if it's not required.
- *                      See NNStreamer documentation (https://nnstreamer.github.io/gst/nnstreamer/tensor_filter/README.html) for the details.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_PERMISSION_DENIED The application does not have the privilege to access to the media storage or external storage.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE Failed to start the pipeline.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_single_open_full (ml_single_h * single, const char *model, const ml_tensors_info_h input_info, const ml_tensors_info_h output_info, ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw, const char *custom_option);
-
-/**
- * @brief Closes the opened model handle.
- * @details Note that this should be called before destroying the inference data by ml_tensors_data_destroy().
- *          If not, the inference engine might try to access the data that is already freed.
- *          And it causes the segmentation fault.
- * @since_tizen 5.5
- * @param[in] single The model handle to be closed.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid (Pipeline is not negotiated yet.)
- */
-int ml_single_close (ml_single_h single);
-
-/**
- * @brief Invokes the model with the given input data.
- * @details Even if the model has flexible input data dimensions,
- *          input data frames of an instance of a model should share the same dimension.
- *          Note that this will wait for the result until the invoke process is done. If an application wants to change the time to wait for an output, set the timeout using ml_single_set_timeout().
- * @since_tizen 5.5
- * @param[in] single The model handle to be inferred.
- * @param[in] input The input data to be inferred.
- * @param[out] output The allocated output buffer. The caller is responsible for freeing the output buffer with ml_tensors_data_destroy().
- * @return @c 0 on success. Otherwise a negative error value.
- * @note If the data for the output buffer is allocated by the neural network framework (ML_NNFW_TYPE_CUSTOM_FILTER supports this),
- *       then this buffer will be freed when closing the @a single automatically by the neural network framework, and will not available for use later.
- *       It is recommended to copy the output buffer from @a output if it is required to use it after the @a single handle is closed.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE Failed to push a buffer into source element.
- * @retval #ML_ERROR_TIMED_OUT Failed to get the result from sink element.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_single_invoke (ml_single_h single, const ml_tensors_data_h input, ml_tensors_data_h *output);
-
-/**
- * @brief Invokes the model with the given input data and fills the @a output data handle. This is generally faster than ml_single_invoke().
- * @details The caller should preallocate memory buffers of the given output handle before calling the API.
- *          Note that ml_single_invoke() allocates memory buffers of the output handle in the API, which may incur memcpy.
- * @since_tizen 6.5
- * @param[in] single The model handle to be inferred.
- * @param[in] input The input data to be inferred.
- * @param[in,out] output The output data to be filled by the API. Output should be preallocated before calling the API.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE Failed to push a buffer into source element.
- * @retval #ML_ERROR_TIMED_OUT Failed to get the result from sink element.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_single_invoke_fast (ml_single_h single, const ml_tensors_data_h input, ml_tensors_data_h output);
-
-/**
- * @brief Invokes the model with the given input data with the given tensors information.
- * @details This function changes the input tensors information for the model, and returns the corresponding output data.
- *          A model/framework may not support changing the information.
- *          Note that this will wait for the result until the invoke process is done. If an application wants to change the time to wait for an output, set the timeout using ml_single_set_timeout().
- * @since_tizen 6.0
- * @param[in] single The model handle to be inferred.
- * @param[in] input The input data to be inferred.
- * @param[in] in_info The handle of input tensors information.
- * @param[out] output The allocated output buffer. The caller is responsible for freeing the output buffer with ml_tensors_data_destroy().
- * @param[out] out_info The handle of output tensors information. The caller is responsible for freeing the information with ml_tensors_info_destroy().
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE Failed to push a buffer into source element.
- * @retval #ML_ERROR_TIMED_OUT Failed to get the result from sink element.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_single_invoke_dynamic (ml_single_h single, const ml_tensors_data_h input, const ml_tensors_info_h in_info, ml_tensors_data_h *output, ml_tensors_info_h *out_info);
-
-/*************
- * UTILITIES *
- *************/
-
-/**
- * @brief Gets the information (tensor dimension, type, name and so on) of required input data for the given model.
- * @details Note that a model may not have such information if its input type is flexible.
- *          The names of tensors are sometimes unavailable (optional), while its dimensions and types are always available.
- * @since_tizen 5.5
- * @param[in] single The model handle.
- * @param[out] info The handle of input tensors information. The caller is responsible for freeing the information with ml_tensors_info_destroy().
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- */
-int ml_single_get_input_info (ml_single_h single, ml_tensors_info_h *info);
-
-/**
- * @brief Gets the information (tensor dimension, type, name and so on) of output data for the given model.
- * @details Note that a model may not have such information if its output type is flexible and output type is not determined statically.
- *          The names of tensors are sometimes unavailable (optional), while its dimensions and types are always available.
- * @since_tizen 5.5
- * @param[in] single The model handle.
- * @param[out] info The handle of output tensors information. The caller is responsible for freeing the information with ml_tensors_info_destroy().
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- */
-int ml_single_get_output_info (ml_single_h single, ml_tensors_info_h *info);
-
-/**
- * @brief Sets the information (tensor dimension, type, name and so on) of required input data for the given model.
- * @details Note that a model/framework may not support changing the information.
- *          Use ml_single_get_input_info() and ml_single_get_output_info() instead for this framework.
- * @since_tizen 6.0
- * @param[in] single The model handle.
- * @param[in] info The handle of input tensors information.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- */
-int ml_single_set_input_info (ml_single_h single, const ml_tensors_info_h info);
-
-/**
- * @brief Sets the maximum amount of time to wait for an output, in milliseconds.
- * @since_tizen 5.5
- * @param[in] single The model handle.
- * @param[in] timeout The time to wait for an output.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- */
-int ml_single_set_timeout (ml_single_h single, unsigned int timeout);
-
-/**
- * @brief Sets the property value for the given model.
- * @details Note that a model/framework may not support changing the property after opening the model.
- * @since_tizen 6.0
- * @param[in] single The model handle.
- * @param[in] name The property name.
- * @param[in] value The property value.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- */
-int ml_single_set_property (ml_single_h single, const char *name, const char *value);
-
-/**
- * @brief Gets the property value for the given model.
- * @since_tizen 6.0
- * @param[in] single The model handle.
- * @param[in] name The property name.
- * @param[out] value The property value. The caller is responsible for freeing the value using g_free().
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- */
-int ml_single_get_property (ml_single_h single, const char *name, char **value);
-
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __TIZEN_MACHINELEARNING_NNSTREAMER_SINGLE_H__ */
diff --git a/api/capi/include/nnstreamer-tizen-internal.h b/api/capi/include/nnstreamer-tizen-internal.h
deleted file mode 100644 (file)
index 15eeed0..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-tizen-internal.h
- * @date       02 October 2019
- * @brief      NNStreamer/Pipeline(main) C-API Header for Tizen Internal API. This header should be used only in Tizen.
- * @author     Jaeyun Jung <jy1210.jung@samsung.com>
- * @bug                No known bugs except for NYI items
- */
-
-#ifndef __TIZEN_MACHINELEARNING_NNSTREAMER_INTERNAL_H__
-#define __TIZEN_MACHINELEARNING_NNSTREAMER_INTERNAL_H__
-
-#include <nnstreamer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * @brief Constructs the pipeline (GStreamer + NNStreamer).
- * @details This function is to construct the pipeline without checking the permission in platform internally. See ml_pipeline_construct() for the details.
- * @since_tizen 5.5
- */
-int ml_pipeline_construct_internal (const char *pipeline_description, ml_pipeline_state_cb cb, void *user_data, ml_pipeline_h *pipe);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __TIZEN_MACHINELEARNING_NNSTREAMER_INTERNAL_H__ */
diff --git a/api/capi/include/nnstreamer.h b/api/capi/include/nnstreamer.h
deleted file mode 100644 (file)
index 406bcff..0000000
+++ /dev/null
@@ -1,1338 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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.h
- * @date 07 March 2019
- * @brief NNStreamer/Pipeline(main) C-API Header.
- *        This allows to construct and control NNStreamer pipelines.
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#ifndef __TIZEN_MACHINELEARNING_NNSTREAMER_H__
-#define __TIZEN_MACHINELEARNING_NNSTREAMER_H__
-
-#include <stddef.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <ml-api-common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-/**
- * @addtogroup CAPI_ML_NNSTREAMER_PIPELINE_MODULE
- * @{
- */
-
-/**
- * @brief The virtual name to set the video source of camcorder in Tizen.
- * @details If an application needs to access the camera device to construct the pipeline, set the virtual name as a video source element.
- *          Note that you have to add '%http://tizen.org/privilege/camera' into the manifest of your application.
- * @since_tizen 5.5
- */
-#define ML_TIZEN_CAM_VIDEO_SRC "tizencamvideosrc"
-
-/**
- * @brief The virtual name to set the audio source of camcorder in Tizen.
- * @details If an application needs to access the recorder device to construct the pipeline, set the virtual name as an audio source element.
- *          Note that you have to add '%http://tizen.org/privilege/recorder' into the manifest of your application.
- * @since_tizen 5.5
- */
-#define ML_TIZEN_CAM_AUDIO_SRC "tizencamaudiosrc"
-
-/**
- * @brief The maximum rank that NNStreamer supports with Tizen APIs.
- * @since_tizen 5.5
- */
-#define ML_TENSOR_RANK_LIMIT  (4)
-
-/**
- * @brief The maximum number of other/tensor instances that other/tensors may have.
- * @since_tizen 5.5
- */
-#define ML_TENSOR_SIZE_LIMIT  (16)
-
-/**
- * @brief The dimensions of a tensor that NNStreamer supports.
- * @since_tizen 5.5
- */
-typedef unsigned int ml_tensor_dimension[ML_TENSOR_RANK_LIMIT];
-
-/**
- * @brief A handle of a tensors metadata instance.
- * @since_tizen 5.5
- */
-typedef void *ml_tensors_info_h;
-
-/**
- * @brief A handle of input or output frames. #ml_tensors_info_h is the handle for tensors metadata.
- * @since_tizen 5.5
- */
-typedef void *ml_tensors_data_h;
-
-/**
- * @brief A handle of an NNStreamer pipeline.
- * @since_tizen 5.5
- */
-typedef void *ml_pipeline_h;
-
-/**
- * @brief A handle of a "sink node" of an NNStreamer pipeline.
- * @since_tizen 5.5
- */
-typedef void *ml_pipeline_sink_h;
-
-/**
- * @brief A handle of a "src node" of an NNStreamer pipeline.
- * @since_tizen 5.5
- */
-typedef void *ml_pipeline_src_h;
-
-/**
- * @brief A handle of a "switch" of an NNStreamer pipeline.
- * @since_tizen 5.5
- */
-typedef void *ml_pipeline_switch_h;
-
-/**
- * @brief A handle of a "valve node" of an NNStreamer pipeline.
- * @since_tizen 5.5
- */
-typedef void *ml_pipeline_valve_h;
-
-/**
- * @brief A handle of a common element (i.e. All GstElement except AppSrc, AppSink, TensorSink, Selector and Valve) of an NNStreamer pipeline.
- * @since_tizen 6.0
- */
-typedef void *ml_pipeline_element_h;
-
-/**
- * @brief A handle of a "custom-easy filter" of an NNStreamer pipeline.
- * @since_tizen 6.0
- */
-typedef void *ml_custom_easy_filter_h;
-
-/**
- * @brief A handle of a "if node" of an NNStreamer pipeline.
- * @since_tizen 6.5
- */
-typedef void *ml_pipeline_if_h;
-
-/**
- * @brief Types of NNFWs.
- * @details To check if a nnfw-type is supported in a system, an application may call the API, ml_check_nnfw_availability().
- * @since_tizen 5.5
- */
-typedef enum {
-  ML_NNFW_TYPE_ANY = 0,               /**< NNFW is not specified (Try to determine the NNFW with file extension). */
-  ML_NNFW_TYPE_CUSTOM_FILTER = 1,     /**< Custom filter (Independent shared object). */
-  ML_NNFW_TYPE_TENSORFLOW_LITE = 2,   /**< Tensorflow-lite (.tflite). */
-  ML_NNFW_TYPE_TENSORFLOW = 3,        /**< Tensorflow (.pb). */
-  ML_NNFW_TYPE_NNFW = 4,              /**< Neural Network Inference framework, which is developed by SR (Samsung Research). */
-  ML_NNFW_TYPE_MVNC = 5,              /**< Intel Movidius Neural Compute SDK (libmvnc). (Since 6.0) */
-  ML_NNFW_TYPE_OPENVINO = 6,          /**< Intel OpenVINO. (Since 6.0) */
-  ML_NNFW_TYPE_VIVANTE = 7,           /**< VeriSilicon's Vivante. (Since 6.0) */
-  ML_NNFW_TYPE_EDGE_TPU = 8,          /**< Google Coral Edge TPU (USB). (Since 6.0) */
-  ML_NNFW_TYPE_ARMNN = 9,             /**< Arm Neural Network framework (support for caffe and tensorflow-lite). (Since 6.0) */
-  ML_NNFW_TYPE_SNPE = 10,             /**< Qualcomm SNPE (Snapdgragon Neural Processing Engine (.dlc). (Since 6.0) */
-  ML_NNFW_TYPE_PYTORCH = 11,          /**< PyTorch (.pt). (Since 6.5) */
-  ML_NNFW_TYPE_NNTR_INF = 12,         /**< Inference supported from NNTrainer, SR On-device Training Framework (Since 6.5) */
-  ML_NNFW_TYPE_SNAP = 0x2001,         /**< SNAP (Samsung Neural Acceleration Platform), only for Android. (Since 6.0) */
-} ml_nnfw_type_e;
-
-/**
- * @brief Types of hardware resources to be used for NNFWs. Note that if the affinity (nnn) is not supported by the driver or hardware, it is ignored.
- * @since_tizen 5.5
- */
-typedef enum {
-  ML_NNFW_HW_ANY          = 0,      /**< Hardware resource is not specified. */
-  ML_NNFW_HW_AUTO         = 1,      /**< Try to schedule and optimize if possible. */
-  ML_NNFW_HW_CPU          = 0x1000, /**< 0x1000: any CPU. 0x1nnn: CPU # nnn-1. */
-  ML_NNFW_HW_CPU_SIMD     = 0x1100, /**< 0x1100: SIMD in CPU. (Since 6.0) */
-  ML_NNFW_HW_CPU_NEON     = 0x1100, /**< 0x1100: NEON (alias for SIMD) in CPU. (Since 6.0) */
-  ML_NNFW_HW_GPU          = 0x2000, /**< 0x2000: any GPU. 0x2nnn: GPU # nnn-1. */
-  ML_NNFW_HW_NPU          = 0x3000, /**< 0x3000: any NPU. 0x3nnn: NPU # nnn-1. */
-  ML_NNFW_HW_NPU_MOVIDIUS = 0x3001, /**< 0x3001: Intel Movidius Stick. (Since 6.0) */
-  ML_NNFW_HW_NPU_EDGE_TPU = 0x3002, /**< 0x3002: Google Coral Edge TPU (USB). (Since 6.0) */
-  ML_NNFW_HW_NPU_VIVANTE  = 0x3003, /**< 0x3003: VeriSilicon's Vivante. (Since 6.0) */
-  ML_NNFW_HW_NPU_SR       = 0x13000, /**< 0x13000: any SR (Samsung Research) made NPU. (Since 6.0) */
-} ml_nnfw_hw_e;
-
-/**
- * @brief Possible data element types of tensor in NNStreamer.
- * @since_tizen 5.5
- */
-typedef enum _ml_tensor_type_e
-{
-  ML_TENSOR_TYPE_INT32 = 0,      /**< Integer 32bit */
-  ML_TENSOR_TYPE_UINT32,         /**< Unsigned integer 32bit */
-  ML_TENSOR_TYPE_INT16,          /**< Integer 16bit */
-  ML_TENSOR_TYPE_UINT16,         /**< Unsigned integer 16bit */
-  ML_TENSOR_TYPE_INT8,           /**< Integer 8bit */
-  ML_TENSOR_TYPE_UINT8,          /**< Unsigned integer 8bit */
-  ML_TENSOR_TYPE_FLOAT64,        /**< Float 64bit */
-  ML_TENSOR_TYPE_FLOAT32,        /**< Float 32bit */
-  ML_TENSOR_TYPE_INT64,          /**< Integer 64bit */
-  ML_TENSOR_TYPE_UINT64,         /**< Unsigned integer 64bit */
-  ML_TENSOR_TYPE_UNKNOWN         /**< Unknown type */
-} ml_tensor_type_e;
-
-/**
- * @brief Enumeration for buffer deallocation policies.
- * @since_tizen 5.5
- */
-typedef enum {
-  ML_PIPELINE_BUF_POLICY_AUTO_FREE      = 0, /**< Default. Application should not deallocate this buffer. NNStreamer will deallocate when the buffer is no more needed. */
-  ML_PIPELINE_BUF_POLICY_DO_NOT_FREE    = 1, /**< This buffer is not to be freed by NNStreamer (i.e., it's a static object). However, be careful: NNStreamer might be accessing this object after the return of the API call. */
-  ML_PIPELINE_BUF_POLICY_MAX,   /**< Max size of #ml_pipeline_buf_policy_e structure. */
-  ML_PIPELINE_BUF_SRC_EVENT_EOS         = 0x10000, /**< Trigger End-Of-Stream event for the corresponding appsrc and ignore the given input value. The corresponding appsrc will no longer accept new data after this. */
-} ml_pipeline_buf_policy_e;
-
-/**
- * @brief Enumeration for pipeline state.
- * @details The pipeline state is described on @ref CAPI_ML_NNSTREAMER_PIPELINE_STATE_DIAGRAM.
- * Refer to https://gstreamer.freedesktop.org/documentation/plugin-development/basics/states.html.
- * @since_tizen 5.5
- */
-typedef enum {
-  ML_PIPELINE_STATE_UNKNOWN                            = 0, /**< Unknown state. Maybe not constructed? */
-  ML_PIPELINE_STATE_NULL                               = 1, /**< GST-State "Null" */
-  ML_PIPELINE_STATE_READY                              = 2, /**< GST-State "Ready" */
-  ML_PIPELINE_STATE_PAUSED                             = 3, /**< GST-State "Paused" */
-  ML_PIPELINE_STATE_PLAYING                            = 4, /**< GST-State "Playing" */
-} ml_pipeline_state_e;
-
-/**
- * @brief Enumeration for switch types.
- * @details This designates different GStreamer filters, "GstInputSelector"/"GstOutputSelector".
- * @since_tizen 5.5
- */
-typedef enum {
-  ML_PIPELINE_SWITCH_OUTPUT_SELECTOR                   = 0, /**< GstOutputSelector */
-  ML_PIPELINE_SWITCH_INPUT_SELECTOR                    = 1, /**< GstInputSelector */
-} ml_pipeline_switch_e;
-
-/**
- * @brief Callback for sink element of NNStreamer pipelines (pipeline's output).
- * @details If an application wants to accept data outputs of an NNStreamer stream, use this callback to get data from the stream. Note that the buffer may be deallocated after the return and this is synchronously called. Thus, if you need the data afterwards, copy the data to another buffer and return fast. Do not spend too much time in the callback. It is recommended to use very small tensors at sinks.
- * @since_tizen 5.5
- * @remarks The @a data can be used only in the callback. To use outside, make a copy.
- * @remarks The @a info can be used only in the callback. To use outside, make a copy.
- * @param[in] data The handle of the tensor output of the pipeline (a single frame. tensor/tensors). Number of tensors is determined by ml_tensors_info_get_count() with the handle 'info'. Note that the maximum number of tensors is 16 (#ML_TENSOR_SIZE_LIMIT).
- * @param[in] info The handle of tensors information (cardinality, dimension, and type of given tensor/tensors).
- * @param[in,out] user_data User application's private data.
- */
-typedef void (*ml_pipeline_sink_cb) (const ml_tensors_data_h data, const ml_tensors_info_h info, void *user_data);
-
-/**
- * @brief Callback for the change of pipeline state.
- * @details If an application wants to get the change of pipeline state, use this callback. This callback can be registered when constructing the pipeline using ml_pipeline_construct(). Do not spend too much time in the callback.
- * @since_tizen 5.5
- * @param[in] state The new state of the pipeline.
- * @param[out] user_data User application's private data.
- */
-typedef void (*ml_pipeline_state_cb) (ml_pipeline_state_e state, void *user_data);
-
-/**
- * @brief Callback for custom condition of tensor_if.
- * @since_tizen 6.5
- * @remarks The @a data can be used only in the callback. To use outside, make a copy.
- * @remarks The @a info can be used only in the callback. To use outside, make a copy.
- * @remarks The @a result can be used only in the callback and should not be released.
- * @param[in] data The handle of the tensor output of the pipeline (a single frame. tensor/tensors). Number of tensors is determined by ml_tensors_info_get_count() with the handle 'info'. Note that the maximum number of tensors is 16 (#ML_TENSOR_SIZE_LIMIT).
- * @param[in] info The handle of tensors information (cardinality, dimension, and type of given tensor/tensors).
- * @param[out] result Result of the user-defined condition. 0 refers to FALSE and a non-zero value refers to TRUE. The application should set the result value for given data.
- * @param[in,out] user_data User application's private data.
- * @return @c 0 on success. Otherwise a negative error value.
- */
-typedef int (*ml_pipeline_if_custom_cb) (const ml_tensors_data_h data, const ml_tensors_info_h info, int *result, void *user_data);
-
-/**
- * @brief Callback to execute the custom-easy filter in NNStreamer pipelines.
- * @details Note that if ml_custom_easy_invoke_cb() returns negative error values, the constructed pipeline does not work properly anymore.
- *          So developers should release the pipeline handle and recreate it again.
- * @since_tizen 6.0
- * @remarks The @a in can be used only in the callback. To use outside, make a copy.
- * @remarks The @a out can be used only in the callback. To use outside, make a copy.
- * @param[in] in The handle of the tensor input (a single frame. tensor/tensors).
- * @param[out] out The handle of the tensor output to be filled (a single frame. tensor/tensors).
- * @param[in,out] user_data User application's private data.
- * @return @c 0 on success. @c 1 to ignore the input data. Otherwise a negative error value.
- */
-typedef int (*ml_custom_easy_invoke_cb) (const ml_tensors_data_h in, ml_tensors_data_h out, void *user_data);
-
-/****************************************************
- ** NNStreamer Pipeline Construction (gst-parse)   **
- ****************************************************/
-/**
- * @brief Constructs the pipeline (GStreamer + NNStreamer).
- * @details Use this function to create gst_parse_launch compatible NNStreamer pipelines.
- * @since_tizen 5.5
- * @remarks If the function succeeds, @a pipe handle must be released using ml_pipeline_destroy().
- * @remarks %http://tizen.org/privilege/mediastorage is needed if @a pipeline_description is relevant to media storage.
- * @remarks %http://tizen.org/privilege/externalstorage is needed if @a pipeline_description is relevant to external storage.
- * @remarks %http://tizen.org/privilege/camera is needed if @a pipeline_description accesses the camera device.
- * @remarks %http://tizen.org/privilege/recorder is needed if @a pipeline_description accesses the recorder device.
- * @param[in] pipeline_description The pipeline description compatible with GStreamer gst_parse_launch(). Refer to GStreamer manual or NNStreamer (https://github.com/nnstreamer/nnstreamer) documentation for examples and the grammar.
- * @param[in] cb The function to be called when the pipeline state is changed. You may set NULL if it's not required.
- * @param[in] user_data Private data for the callback. This value is passed to the callback when it's invoked.
- * @param[out] pipe The NNStreamer pipeline handler from the given description.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_PERMISSION_DENIED The application does not have the required privilege to access to the media storage, external storage, microphone, or camera.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid. (Pipeline is not negotiated yet.)
- * @retval #ML_ERROR_STREAMS_PIPE Pipeline construction is failed because of wrong parameter or initialization failure.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory to construct the pipeline.
- *
- * @pre The pipeline state should be #ML_PIPELINE_STATE_UNKNOWN or #ML_PIPELINE_STATE_NULL.
- * @post The pipeline state will be #ML_PIPELINE_STATE_PAUSED in the same thread.
- */
-int ml_pipeline_construct (const char *pipeline_description, ml_pipeline_state_cb cb, void *user_data, ml_pipeline_h *pipe);
-
-/**
- * @brief Destroys the pipeline.
- * @details Use this function to destroy the pipeline constructed with ml_pipeline_construct().
- * @since_tizen 5.5
- * @param[in] pipe The pipeline to be destroyed.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER The parameter is invalid. (Pipeline is not negotiated yet.)
- * @retval #ML_ERROR_STREAMS_PIPE Failed to access the pipeline state.
- *
- * @pre The pipeline state should be #ML_PIPELINE_STATE_PLAYING or #ML_PIPELINE_STATE_PAUSED.
- * @post The pipeline state will be #ML_PIPELINE_STATE_NULL.
- */
-int ml_pipeline_destroy (ml_pipeline_h pipe);
-
-/**
- * @brief Gets the state of pipeline.
- * @details Gets the state of the pipeline handle returned by ml_pipeline_construct().
- * @since_tizen 5.5
- * @param[in] pipe The pipeline handle.
- * @param[out] state The pipeline state.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid. (Pipeline is not negotiated yet.)
- * @retval #ML_ERROR_STREAMS_PIPE Failed to get state from the pipeline.
- */
-int ml_pipeline_get_state (ml_pipeline_h pipe, ml_pipeline_state_e *state);
-
-/****************************************************
- ** NNStreamer Pipeline Start/Stop Control         **
- ****************************************************/
-/**
- * @brief Starts the pipeline, asynchronously.
- * @details The pipeline handle returned by ml_pipeline_construct() is started.
- *          Note that this is asynchronous function. State might be "pending".
- *          If you need to get the changed state, add a callback while constructing a pipeline with ml_pipeline_construct().
- * @since_tizen 5.5
- * @param[in] pipe The pipeline handle.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid. (Pipeline is not negotiated yet.)
- * @retval #ML_ERROR_STREAMS_PIPE Failed to start the pipeline.
- *
- * @pre The pipeline state should be #ML_PIPELINE_STATE_PAUSED.
- * @post The pipeline state will be #ML_PIPELINE_STATE_PLAYING.
- */
-int ml_pipeline_start (ml_pipeline_h pipe);
-
-/**
- * @brief Stops the pipeline, asynchronously.
- * @details The pipeline handle returned by ml_pipeline_construct() is stopped.
- *          Note that this is asynchronous function. State might be "pending".
- *          If you need to get the changed state, add a callback while constructing a pipeline with ml_pipeline_construct().
- * @since_tizen 5.5
- * @param[in] pipe The pipeline to be stopped.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid. (Pipeline is not negotiated yet.)
- * @retval #ML_ERROR_STREAMS_PIPE Failed to stop the pipeline.
- *
- * @pre The pipeline state should be #ML_PIPELINE_STATE_PLAYING.
- * @post The pipeline state will be #ML_PIPELINE_STATE_PAUSED.
- */
-int ml_pipeline_stop (ml_pipeline_h pipe);
-
-/****************************************************
- ** NNStreamer Pipeline Sink/Src Control           **
- ****************************************************/
-/**
- * @brief Registers a callback for sink node of NNStreamer pipelines.
- * @since_tizen 5.5
- * @remarks If the function succeeds, @a sink_handle handle must be unregistered using ml_pipeline_sink_unregister().
- * @param[in] pipe The pipeline to be attached with a sink node.
- * @param[in] sink_name The name of sink node, described with ml_pipeline_construct().
- * @param[in] cb The function to be called by the sink node.
- * @param[in] user_data Private data for the callback. This value is passed to the callback when it's invoked.
- * @param[out] sink_handle The sink handle.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid. (Not negotiated, @a sink_name is not found, or @a sink_name has an invalid type.)
- * @retval #ML_ERROR_STREAMS_PIPE Failed to connect a signal to sink element.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- *
- * @pre The pipeline state should be #ML_PIPELINE_STATE_PAUSED.
- */
-int ml_pipeline_sink_register (ml_pipeline_h pipe, const char *sink_name, ml_pipeline_sink_cb cb, void *user_data, ml_pipeline_sink_h *sink_handle);
-
-/**
- * @brief Unregisters a callback for sink node of NNStreamer pipelines.
- * @since_tizen 5.5
- * @param[in] sink_handle The sink handle to be unregistered.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- *
- * @pre The pipeline state should be #ML_PIPELINE_STATE_PAUSED.
- */
-int ml_pipeline_sink_unregister (ml_pipeline_sink_h sink_handle);
-
-/**
- * @brief Gets a handle to operate as a src node of NNStreamer pipelines.
- * @since_tizen 5.5
- * @remarks If the function succeeds, @a src_handle handle must be released using ml_pipeline_src_release_handle().
- * @param[in] pipe The pipeline to be attached with a src node.
- * @param[in] src_name The name of src node, described with ml_pipeline_construct().
- * @param[out] src_handle The src handle.
- * @return 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE Failed to get src element.
- * @retval #ML_ERROR_TRY_AGAIN The pipeline is not ready yet.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_pipeline_src_get_handle (ml_pipeline_h pipe, const char *src_name, ml_pipeline_src_h *src_handle);
-
-/**
- * @brief Releases the given src handle.
- * @since_tizen 5.5
- * @param[in] src_handle The src handle to be released.
- * @return 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_pipeline_src_release_handle (ml_pipeline_src_h src_handle);
-
-/**
- * @brief Adds an input data frame.
- * @since_tizen 5.5
- * @param[in] src_handle The source handle returned by ml_pipeline_src_get_handle().
- * @param[in] data The handle of input tensors, in the format of tensors info given by ml_pipeline_src_get_tensors_info().
- *                 This function takes ownership of the data if @a policy is #ML_PIPELINE_BUF_POLICY_AUTO_FREE.
- * @param[in] policy The policy of buffer deallocation. The policy value may include buffer deallocation mechanisms or event triggers for appsrc elements. If event triggers are provided, these functions will not give input data to the appsrc element, but will trigger the given event only.
- * @return 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE The pipeline has inconsistent pad caps. (Pipeline is not negotiated yet.)
- * @retval #ML_ERROR_TRY_AGAIN The pipeline is not ready yet.
- */
-int ml_pipeline_src_input_data (ml_pipeline_src_h src_handle, ml_tensors_data_h data, ml_pipeline_buf_policy_e policy);
-
-/**
- * @brief Gets a handle for the tensors information of given src node.
- * @details If the media type is not other/tensor or other/tensors, @a info handle may not be correct. If want to use other media types, you MUST set the correct properties.
- * @since_tizen 5.5
- * @remarks If the function succeeds, @a info handle must be released using ml_tensors_info_destroy().
- * @param[in] src_handle The source handle returned by ml_pipeline_src_get_handle().
- * @param[out] info The handle of tensors information.
- * @return 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE The pipeline has inconsistent pad caps. (Pipeline is not negotiated yet.)
- * @retval #ML_ERROR_TRY_AGAIN The pipeline is not ready yet.
- */
-int ml_pipeline_src_get_tensors_info (ml_pipeline_src_h src_handle, ml_tensors_info_h *info);
-
-/****************************************************
- ** NNStreamer Pipeline Switch/Valve Control       **
- ****************************************************/
-
-/**
- * @brief Gets a handle to operate a "GstInputSelector"/"GstOutputSelector" node of NNStreamer pipelines.
- * @details Refer to https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-input-selector.html for input selectors.
- *          Refer to https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-output-selector.html for output selectors.
- * @since_tizen 5.5
- * @remarks If the function succeeds, @a switch_handle handle must be released using ml_pipeline_switch_release_handle().
- * @param[in] pipe The pipeline to be managed.
- * @param[in] switch_name The name of switch (InputSelector/OutputSelector).
- * @param[out] switch_type The type of the switch. If NULL, it is ignored.
- * @param[out] switch_handle The switch handle.
- * @return 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_pipeline_switch_get_handle (ml_pipeline_h pipe, const char *switch_name, ml_pipeline_switch_e *switch_type, ml_pipeline_switch_h *switch_handle);
-
-/**
- * @brief Releases the given switch handle.
- * @since_tizen 5.5
- * @param[in] switch_handle The handle to be released.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_pipeline_switch_release_handle (ml_pipeline_switch_h switch_handle);
-
-/**
- * @brief Controls the switch with the given handle to select input/output nodes(pads).
- * @since_tizen 5.5
- * @param[in] switch_handle The switch handle returned by ml_pipeline_switch_get_handle().
- * @param[in] pad_name The name of the chosen pad to be activated. Use ml_pipeline_switch_get_pad_list() to list the available pad names.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_pipeline_switch_select (ml_pipeline_switch_h switch_handle, const char *pad_name);
-
-/**
- * @brief Gets the pad names of a switch.
- * @since_tizen 5.5
- * @remarks If the function succeeds, @a list and its contents should be released using g_free(). Refer the below sample code.
- * @param[in] switch_handle The switch handle returned by ml_pipeline_switch_get_handle().
- * @param[out] list NULL terminated array of char*. The caller must free each string (char*) in the list and free the list itself.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE The element is not both input and output switch (Internal data inconsistency).
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- *
- * Here is an example of the usage:
- * @code
- * int status;
- * gchar *pipeline;
- * ml_pipeline_h handle;
- * ml_pipeline_switch_e switch_type;
- * ml_pipeline_switch_h switch_handle;
- * gchar **node_list = NULL;
- *
- * // pipeline description
- * pipeline = g_strdup ("videotestsrc is-live=true ! videoconvert ! tensor_converter ! output-selector name=outs "
- *     "outs.src_0 ! tensor_sink name=sink0 async=false "
- *     "outs.src_1 ! tensor_sink name=sink1 async=false");
- *
- * status = ml_pipeline_construct (pipeline, NULL, NULL, &handle);
- * if (status != ML_ERROR_NONE) {
- *   // handle error case
- *   goto error;
- * }
- *
- * status = ml_pipeline_switch_get_handle (handle, "outs", &switch_type, &switch_handle);
- * if (status != ML_ERROR_NONE) {
- *   // handle error case
- *   goto error;
- * }
- *
- * status = ml_pipeline_switch_get_pad_list (switch_handle, &node_list);
- * if (status != ML_ERROR_NONE) {
- *   // handle error case
- *   goto error;
- * }
- *
- * if (node_list) {
- *   gchar *name = NULL;
- *   guint idx = 0;
- *
- *   while ((name = node_list[idx++]) != NULL) {
- *     // node name is 'src_0' or 'src_1'
- *
- *     // release name
- *     g_free (name);
- *   }
- *   // release list of switch pads
- *   g_free (node_list);
- * }
- *
- * error:
- * ml_pipeline_switch_release_handle (switch_handle);
- * ml_pipeline_destroy (handle);
- * g_free (pipeline);
- * @endcode
- */
-int ml_pipeline_switch_get_pad_list (ml_pipeline_switch_h switch_handle, char ***list);
-
-/**
- * @brief Gets a handle to operate a "GstValve" node of NNStreamer pipelines.
- * @details Refer to https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-valve.html for more information.
- * @since_tizen 5.5
- * @remarks If the function succeeds, @a valve_handle handle must be released using ml_pipeline_valve_release_handle().
- * @param[in] pipe The pipeline to be managed.
- * @param[in] valve_name The name of valve (Valve).
- * @param[out] valve_handle The valve handle.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_pipeline_valve_get_handle (ml_pipeline_h pipe, const char *valve_name, ml_pipeline_valve_h *valve_handle);
-
-/**
- * @brief Releases the given valve handle.
- * @since_tizen 5.5
- * @param[in] valve_handle The handle to be released.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_pipeline_valve_release_handle (ml_pipeline_valve_h valve_handle);
-
-/**
- * @brief Controls the valve with the given handle.
- * @since_tizen 5.5
- * @param[in] valve_handle The valve handle returned by ml_pipeline_valve_get_handle().
- * @param[in] open @c true to open(let the flow pass), @c false to close (drop & stop the flow).
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_pipeline_valve_set_open (ml_pipeline_valve_h valve_handle, bool open);
-
-/********************************************************
- ** NNStreamer Element Property Control in Pipeline    **
- ********************************************************/
-
-/**
- * @brief Gets an element handle in NNStreamer pipelines to control its properties.
- * @since_tizen 6.0
- * @remarks If the function succeeds, @a elem_h handle must be released using ml_pipeline_element_release_handle().
- * @param[in] pipe The pipeline to be managed.
- * @param[in] element_name The name of element to control.
- * @param[out] elem_h The element handle.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- *
- * Here is an example of the usage:
- * @code
- * ml_pipeline_h handle = nullptr;
- * ml_pipeline_element_h demux_h = nullptr;
- * gchar *pipeline;
- * gchar *ret_tensorpick;
- * int status;
- *
- * pipeline = g_strdup("videotestsrc ! video/x-raw,format=RGB,width=640,height=480 ! videorate max-rate=1 ! " \
- *    "tensor_converter ! tensor_mux ! tensor_demux name=demux ! tensor_sink");
- *
- * // Construct a pipeline
- * status = ml_pipeline_construct (pipeline, NULL, NULL, &handle);
- * if (status != ML_ERROR_NONE) {
- *  // handle error case
- *  goto error;
- * }
- *
- * // Get the handle of target element
- * status = ml_pipeline_element_get_handle (handle, "demux", &demux_h);
- * if (status != ML_ERROR_NONE) {
- *  // handle error case
- *  goto error;
- * }
- *
- * // Set the string value of given element's property
- * status = ml_pipeline_element_set_property_string (demux_h, "tensorpick", "1,2");
- * if (status != ML_ERROR_NONE) {
- *  // handle error case
- *  goto error;
- * }
- *
- * // Get the string value of given element's property
- * status = ml_pipeline_element_get_property_string (demux_h, "tensorpick", &ret_tensorpick);
- * if (status != ML_ERROR_NONE) {
- *  // handle error case
- *  goto error;
- * }
- * // check the property value of given element
- * if (!g_str_equal (ret_tensorpick, "1,2")) {
- *  // handle error case
- *  goto error;
- * }
- *
- * error:
- *  ml_pipeline_element_release_handle (demux_h);
- *  ml_pipeline_destroy (handle);
- * g_free(pipeline);
- * @endcode
- */
-int ml_pipeline_element_get_handle (ml_pipeline_h pipe, const char *element_name, ml_pipeline_element_h *elem_h);
-
-/**
- * @brief Releases the given element handle.
- * @since_tizen 6.0
- * @param[in] elem_h The handle to be released.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_pipeline_element_release_handle (ml_pipeline_element_h elem_h);
-
-/**
- * @brief Sets the boolean value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[in] value The boolean value to be set.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the type is not boolean.
- */
-int ml_pipeline_element_set_property_bool (ml_pipeline_element_h elem_h, const char *property_name, const int32_t value);
-
-/**
- * @brief Sets the string value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[in] value The string value to be set.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the type is not string.
- */
-int ml_pipeline_element_set_property_string (ml_pipeline_element_h elem_h, const char *property_name, const char *value);
-
-/**
- * @brief Sets the integer value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[in] value The integer value to be set.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the type is not integer.
- */
-int ml_pipeline_element_set_property_int32 (ml_pipeline_element_h elem_h, const char *property_name, const int32_t value);
-
-/**
- * @brief Sets the integer 64bit value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[in] value The integer value to be set.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the type is not integer.
- */
-int ml_pipeline_element_set_property_int64 (ml_pipeline_element_h elem_h, const char *property_name, const int64_t value);
-
-/**
- * @brief Sets the unsigned integer value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[in] value The unsigned integer value to be set.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the type is not unsigned integer.
- */
-int ml_pipeline_element_set_property_uint32 (ml_pipeline_element_h elem_h, const char *property_name, const uint32_t value);
-
-/**
- * @brief Sets the unsigned integer 64bit value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[in] value The unsigned integer 64bit value to be set.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the type is not unsigned integer.
- */
-int ml_pipeline_element_set_property_uint64 (ml_pipeline_element_h elem_h, const char *property_name, const uint64_t value);
-
-/**
- * @brief Sets the floating point value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @remarks This function supports all types of floating point values such as Double and Float.
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[in] value The floating point integer value to be set.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the type is not floating point number.
- */
-int ml_pipeline_element_set_property_double (ml_pipeline_element_h elem_h, const char *property_name, const double value);
-
-/**
- * @brief Sets the enumeration value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @remarks Enumeration value is set as an unsigned integer value and developers can get this information using gst-inspect tool.
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[in] value The unsigned integer value to be set, which is corresponding to Enumeration value.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the type is not unsigned integer.
- */
-int ml_pipeline_element_set_property_enum (ml_pipeline_element_h elem_h, const char *property_name, const uint32_t value);
-
-/**
- * @brief Gets the boolean value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[out] value The boolean value of given property.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the third parameter is NULL.
- */
-int ml_pipeline_element_get_property_bool (ml_pipeline_element_h elem_h, const char *property_name, int32_t *value);
-
-/**
- * @brief Gets the string value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[out] value The string value of given property.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the third parameter is NULL.
- */
-int ml_pipeline_element_get_property_string (ml_pipeline_element_h elem_h, const char *property_name, char **value);
-
-/**
- * @brief Gets the integer value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[out] value The integer value of given property.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the third parameter is NULL.
- */
-int ml_pipeline_element_get_property_int32 (ml_pipeline_element_h elem_h, const char *property_name, int32_t *value);
-
-/**
- * @brief Gets the integer 64bit value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[out] value The integer 64bit value of given property.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the third parameter is NULL.
- */
-int ml_pipeline_element_get_property_int64 (ml_pipeline_element_h elem_h, const char *property_name, int64_t *value);
-
-/**
- * @brief Gets the unsigned integer value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[out] value The unsigned integer value of given property.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the third parameter is NULL.
- */
-int ml_pipeline_element_get_property_uint32 (ml_pipeline_element_h elem_h, const char *property_name, uint32_t *value);
-
-/**
- * @brief Gets the unsigned integer 64bit value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[out] value The unsigned integer 64bit value of given property.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the third parameter is NULL.
- */
-int ml_pipeline_element_get_property_uint64 (ml_pipeline_element_h elem_h, const char *property_name, uint64_t *value);
-
-/**
- * @brief Gets the floating point value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @remarks This function supports all types of floating point values such as Double and Float.
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[out] value The floating point value of given property.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the third parameter is NULL.
- */
-int ml_pipeline_element_get_property_double (ml_pipeline_element_h elem_h, const char *property_name, double *value);
-
-/**
- * @brief Gets the enumeration value of element's property in NNStreamer pipelines.
- * @since_tizen 6.0
- * @remarks Enumeration value is get as an unsigned integer value and developers can get this information using gst-inspect tool.
- * @param[in] elem_h The target element handle.
- * @param[in] property_name The name of the property.
- * @param[out] value The unsigned integer value of given property, which is corresponding to Enumeration value.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given property name does not exist or the third parameter is NULL.
- */
-int ml_pipeline_element_get_property_enum (ml_pipeline_element_h elem_h, const char *property_name, uint32_t *value);
-
-/****************************************************
- ** NNStreamer Pipeline tensor_if Control          **
- ****************************************************/
-/**
- * @brief Registers a tensor_if custom callback.
- * @details If the if-condition is complex and cannot be expressed with tensor_if expressions, you can define custom condition.
- * @since_tizen 6.5
- * @remarks If the function succeeds, @a if_custom handle must be released using ml_pipeline_tensor_if_custom_unregister().
- * @param[in] name The name of custom condition
- * @param[in] cb The function to be called when the pipeline runs.
- * @param[in] user_data Private data for the callback. This value is passed to the callback when it's invoked.
- * @param[out] if_custom The tensor_if handler.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER The parameter is invalid.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory to register the custom callback.
- * @retval #ML_ERROR_STREAMS_PIPE Failed to register the custom callback.
- * @warning A custom condition of the tensor_if is registered to the process globally.
- *          If the custom condition "X" is registered, this "X" may be referred in any pipelines of the current process.
- *          So, be careful not to use the same condition name when using multiple pipelines.
- *
- * Here is an example of the usage:
- * @code
- * // Define callback for tensor_if custom condition.
- * static int tensor_if_custom_cb (const ml_tensors_data_h data, const ml_tensors_info_h info, int *result, void *user_data)
- * {
- *   // Describe the conditions and pass the result.
- *   // Result 0 refers to FALSE and a non-zero value refers to TRUE.
- *   *result = 1;
- *   // Return 0 if there is no error.
- *   return 0;
- * }
- *
- * // The pipeline description (input data with dimension 2:1:1:1 and type int8 will be passed to tensor_if custom condition. Depending on the result, proceed to true or false paths.)
- * const char pipeline[] = "appsrc ! other/tensor,dimension=(string)2:1:1:1,type=(string)int8,framerate=(fraction)0/1 ! tensor_if name=tif compared-value=CUSTOM compared-value-option=tif_custom_cb_name then=PASSTHROUGH else=PASSTHROUGH tif.src_0 ! tensor_sink name=true_condition async=false tif.src_1 ! tensor_sink name=false_condition async=false"
- * int status;
- * ml_pipeline_h pipe;
- * ml_pipeline_if_h custom;
- *
- * // Register tensor_if custom with name 'tif_custom_cb_name'.
- * status = ml_pipeline_tensor_if_custom_register ("tif_custom_cb_name", tensor_if_custom_cb, NULL, &custom);
- * if (status != ML_ERROR_NONE) {
- *   // Handle error case.
- *   goto error;
- * }
- *
- * // Construct the pipeline.
- * status = ml_pipeline_construct (pipeline, NULL, NULL, &pipe);
- * if (status != ML_ERROR_NONE) {
- *   // Handle error case.
- *   goto error;
- * }
- *
- * // Start the pipeline and execute the tensor.
- * ml_pipeline_start (pipe);
- *
- * error:
- * // Destroy the pipeline and unregister tensor_if custom.
- * ml_pipeline_stop (pipe);
- * ml_pipeline_destroy (pipe);
- * ml_pipeline_tensor_if_custom_unregister (custom);
- *
- * @endcode
- */
-int ml_pipeline_tensor_if_custom_register (const char *name, ml_pipeline_if_custom_cb cb, void *user_data, ml_pipeline_if_h *if_custom);
-
-/**
- * @brief Unregisters the tensor_if custom callback.
- * @details Use this function to release and unregister the tensor_if custom callback.
- * @since_tizen 6.5
- * @param[in] if_custom The tensor_if handle to be unregistered.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER The parameter is invalid.
- * @retval #ML_ERROR_STREAMS_PIPE Failed to unregister the custom callback.
- */
-int ml_pipeline_tensor_if_custom_unregister (ml_pipeline_if_h if_custom);
-
-/****************************************************
- ** NNStreamer Utilities                           **
- ****************************************************/
-/**
- * @brief Creates a tensors information handle with default value.
- * @since_tizen 5.5
- * @param[out] info The handle of tensors information.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_tensors_info_create (ml_tensors_info_h *info);
-
-/**
- * @brief Frees the given handle of a tensors information.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @return 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_destroy (ml_tensors_info_h info);
-
-/**
- * @brief Validates the given tensors information.
- * @details If the function returns an error, @a valid may not be changed.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information to be validated.
- * @param[out] valid @c true if it's valid, @c false if it's invalid.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_validate (const ml_tensors_info_h info, bool *valid);
-
-/**
- * @brief Copies the tensors information.
- * @since_tizen 5.5
- * @param[out] dest A destination handle of tensors information.
- * @param[in] src The tensors information to be copied.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_clone (ml_tensors_info_h dest, const ml_tensors_info_h src);
-
-/**
- * @brief Sets the number of tensors with given handle of tensors information.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @param[in] count The number of tensors.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_set_count (ml_tensors_info_h info, unsigned int count);
-
-/**
- * @brief Gets the number of tensors with given handle of tensors information.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @param[out] count The number of tensors.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_get_count (ml_tensors_info_h info, unsigned int *count);
-
-/**
- * @brief Sets the tensor name with given handle of tensors information.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @param[in] index The index of the tensor to be updated.
- * @param[in] name The tensor name to be set.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_set_tensor_name (ml_tensors_info_h info, unsigned int index, const char *name);
-
-/**
- * @brief Gets the tensor name with given handle of tensors information.
- * @since_tizen 5.5
- * @remarks Before 6.0 this function returned the internal pointer so application developers do not need to free. Since 6.0 the name string is internally copied and returned. So if the function succeeds, @a name should be released using g_free().
- * @param[in] info The handle of tensors information.
- * @param[in] index The index of the tensor.
- * @param[out] name The tensor name.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_get_tensor_name (ml_tensors_info_h info, unsigned int index, char **name);
-
-/**
- * @brief Sets the tensor type with given handle of tensors information.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @param[in] index The index of the tensor to be updated.
- * @param[in] type The tensor type to be set.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_set_tensor_type (ml_tensors_info_h info, unsigned int index, const ml_tensor_type_e type);
-
-/**
- * @brief Gets the tensor type with given handle of tensors information.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @param[in] index The index of the tensor.
- * @param[out] type The tensor type.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_get_tensor_type (ml_tensors_info_h info, unsigned int index, ml_tensor_type_e *type);
-
-/**
- * @brief Sets the tensor dimension with given handle of tensors information.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @param[in] index The index of the tensor to be updated.
- * @param[in] dimension The tensor dimension to be set.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_set_tensor_dimension (ml_tensors_info_h info, unsigned int index, const ml_tensor_dimension dimension);
-
-/**
- * @brief Gets the tensor dimension with given handle of tensors information.
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @param[in] index The index of the tensor.
- * @param[out] dimension The tensor dimension.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_get_tensor_dimension (ml_tensors_info_h info, unsigned int index, ml_tensor_dimension dimension);
-
-/**
- * @brief Gets the size of tensors data in the given tensors information handle in bytes.
- * @details If an application needs to get the total byte size of tensors, set the @a index '-1'. Note that the maximum number of tensors is 16 (#ML_TENSOR_SIZE_LIMIT).
- * @since_tizen 5.5
- * @param[in] info The handle of tensors information.
- * @param[in] index The index of the tensor.
- * @param[out] data_size The byte size of tensor data.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_info_get_tensor_size (ml_tensors_info_h info, int index, size_t *data_size);
-
-/**
- * @brief Creates a tensor data frame with the given tensors information.
- * @since_tizen 5.5
- * @remarks Before 6.0, this function returned #ML_ERROR_STREAMS_PIPE in case of an internal error. Since 6.0, #ML_ERROR_OUT_OF_MEMORY is returned in such cases, so #ML_ERROR_STREAMS_PIPE is not returned by this function anymore.
- * @param[in] info The handle of tensors information for the allocation.
- * @param[out] data The handle of tensors data. The caller is responsible for freeing the allocated data with ml_tensors_data_destroy().
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory.
- */
-int ml_tensors_data_create (const ml_tensors_info_h info, ml_tensors_data_h *data);
-
-/**
- * @brief Frees the given tensors' data handle.
- * @details Note that the opened handle should be closed before calling this function in the case of a single API.
- *          If not, the inference engine might try to access the data that is already freed.
- *          And it causes the segmentation fault.
- * @since_tizen 5.5
- * @param[in] data The handle of tensors data.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_data_destroy (ml_tensors_data_h data);
-
-/**
- * @brief Gets a tensor data of given handle.
- * @details This returns the pointer of memory block in the handle. Do not deallocate the returned tensor data.
- * @since_tizen 5.5
- * @param[in] data The handle of tensors data.
- * @param[in] index The index of the tensor.
- * @param[out] raw_data Raw tensor data in the handle.
- * @param[out] data_size Byte size of tensor data.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_data_get_tensor_data (ml_tensors_data_h data, unsigned int index, void **raw_data, size_t *data_size);
-
-/**
- * @brief Copies a tensor data to given handle.
- * @since_tizen 5.5
- * @param[in] data The handle of tensors data.
- * @param[in] index The index of the tensor.
- * @param[in] raw_data Raw tensor data to be copied.
- * @param[in] data_size Byte size of raw data.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_tensors_data_set_tensor_data (ml_tensors_data_h data, unsigned int index, const void *raw_data, const size_t data_size);
-
-/**
- * @brief Checks the availability of the given execution environments.
- * @details If the function returns an error, @a available may not be changed.
- * @since_tizen 5.5
- * @param[in] nnfw Check if the nnfw is available in the system.
- *               Set #ML_NNFW_TYPE_ANY to skip checking nnfw.
- * @param[in] hw Check if the hardware is available in the system.
- *               Set #ML_NNFW_HW_ANY to skip checking hardware.
- * @param[out] available @c true if it's available, @c false if it's not available.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful and the environments are available.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_check_nnfw_availability (ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw, bool *available);
-
-/**
- * @brief Checks if the element is registered and available on the pipeline.
- * @details If the function returns an error, @a available may not be changed.
- * @since_tizen 6.5
- * @param[in] element_name The name of element.
- * @param[out] available @c true if it's available, @c false if it's not available.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful and the environments are available.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int ml_check_element_availability (const char *element_name, bool *available);
-
-/**
- * @brief Registers a custom filter.
- * @details NNStreamer provides an interface for processing the tensors with 'custom-easy' framework which can execute without independent shared object.
- *          Using this function, the application can easily register and execute the processing code.
- *          If a custom filter with same name exists, this will be failed and return the error code #ML_ERROR_INVALID_PARAMETER.
- *          Note that if ml_custom_easy_invoke_cb() returns negative error values, the constructed pipeline does not work properly anymore.
- *          So developers should release the pipeline handle and recreate it again.
- * @since_tizen 6.0
- * @remarks If the function succeeds, @a custom handle must be released using ml_pipeline_custom_easy_filter_unregister().
- * @param[in] name The name of custom filter.
- * @param[in] in The handle of input tensors information.
- * @param[in] out The handle of output tensors information.
- * @param[in] cb The function to be called when the pipeline runs.
- * @param[in] user_data Private data for the callback. This value is passed to the callback when it's invoked.
- * @param[out] custom The custom filter handler.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER The parameter is invalid, or duplicated name exists.
- * @retval #ML_ERROR_OUT_OF_MEMORY Failed to allocate required memory to register the custom filter.
- *
- * Here is an example of the usage:
- * @code
- * // Define invoke callback.
- * static int custom_filter_invoke_cb (const ml_tensors_data_h in, ml_tensors_data_h out, void *user_data)
- * {
- *   // Get input tensors using data handle 'in', and fill output tensors using data handle 'out'.
- * }
- *
- * // The pipeline description (input data with dimension 2:1:1:1 and type int8 will be passed to custom filter 'my-custom-filter', which converts data type to float32 and processes tensors.)
- * const char pipeline[] = "appsrc ! other/tensor,dimension=(string)2:1:1:1,type=(string)int8,framerate=(fraction)0/1 ! tensor_filter framework=custom-easy model=my-custom-filter ! tensor_sink";
- * int status;
- * ml_pipeline_h pipe;
- * ml_custom_easy_filter_h custom;
- * ml_tensors_info_h in_info, out_info;
- * ml_tensor_dimension dim = { 2, 1, 1, 1 };
- *
- * // Set input and output tensors information.
- * ml_tensors_info_create (&in_info);
- * ml_tensors_info_set_count (in_info, 1);
- * ml_tensors_info_set_tensor_type (in_info, 0, ML_TENSOR_TYPE_INT8);
- * ml_tensors_info_set_tensor_dimension (in_info, 0, dim);
- *
- * ml_tensors_info_create (&out_info);
- * ml_tensors_info_set_count (out_info, 1);
- * ml_tensors_info_set_tensor_type (out_info, 0, ML_TENSOR_TYPE_FLOAT32);
- * ml_tensors_info_set_tensor_dimension (out_info, 0, dim);
- *
- * // Register custom filter with name 'my-custom-filter' ('custom-easy' framework).
- * status = ml_pipeline_custom_easy_filter_register ("my-custom-filter", in_info, out_info, custom_filter_invoke_cb, NULL, &custom);
- * if (status != ML_ERROR_NONE) {
- *   // Handle error case.
- *   goto error;
- * }
- *
- * // Construct the pipeline.
- * status = ml_pipeline_construct (pipeline, NULL, NULL, &pipe);
- * if (status != ML_ERROR_NONE) {
- *   // Handle error case.
- *   goto error;
- * }
- *
- * // Start the pipeline and execute the tensor.
- * ml_pipeline_start (pipe);
- *
- * error:
- * // Destroy the pipeline and unregister custom filter.
- * ml_pipeline_stop (pipe);
- * ml_pipeline_destroy (handle);
- * ml_pipeline_custom_easy_filter_unregister (custom);
- * @endcode
- */
-int ml_pipeline_custom_easy_filter_register (const char *name, const ml_tensors_info_h in, const ml_tensors_info_h out, ml_custom_easy_invoke_cb cb, void *user_data, ml_custom_easy_filter_h *custom);
-
-/**
- * @brief Unregisters the custom filter.
- * @details Use this function to release and unregister the custom filter.
- * @since_tizen 6.0
- * @param[in] custom The custom filter to be unregistered.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful.
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
- * @retval #ML_ERROR_INVALID_PARAMETER The parameter is invalid.
- */
-int ml_pipeline_custom_easy_filter_unregister (ml_custom_easy_filter_h custom);
-
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __TIZEN_MACHINELEARNING_NNSTREAMER_H__ */
diff --git a/api/capi/include/platform/tizen_error.h b/api/capi/include/platform/tizen_error.h
deleted file mode 100644 (file)
index 53db494..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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 tizen_error.h
- * @date 24 October 2019
- * @brief C-API internal header emulating tizen_error.h for Non-Tizen platforms
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author Wook Song <wook16.song@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#ifndef __NTZN_TIZEN_ERROR_H__
-#define __NTZN_TIZEN_ERROR_H__
-
-#include <errno.h>
-
-/**
- @ref: https://gitlab.freedesktop.org/dude/gst-plugins-base/commit/89095e7f91cfbfe625ec2522da49053f1f98baf8
- */
-#if !defined(ESTRPIPE)
-#define ESTRPIPE EPIPE
-#endif /* !defined(ESTRPIPE) */
-
-#define TIZEN_ERROR_NONE (0)
-#define TIZEN_ERROR_INVALID_PARAMETER (-EINVAL)
-#define TIZEN_ERROR_STREAMS_PIPE (-ESTRPIPE)
-#define TIZEN_ERROR_TRY_AGAIN (-EAGAIN)
-#define TIZEN_ERROR_UNKNOWN (-1073741824LL)
-#define TIZEN_ERROR_TIMED_OUT (TIZEN_ERROR_UNKNOWN + 1)
-#define TIZEN_ERROR_NOT_SUPPORTED (TIZEN_ERROR_UNKNOWN + 2)
-#define TIZEN_ERROR_PERMISSION_DENIED (-EACCES)
-#define TIZEN_ERROR_OUT_OF_MEMORY (-ENOMEM)
-
-#endif /* __NTZN_TIZEN_ERROR_H__ */
diff --git a/api/capi/meson.build b/api/capi/meson.build
deleted file mode 100644 (file)
index 5f650c1..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-if meson.project_name() != 'nnstreamer'
-
-  project('capi-nnstreamer', 'c',
-    version: '0.1',
-    license: ['LGPL-2.1'],
-    meson_version: '>=0.50.0',
-    default_options: [
-      'werror=true',
-      'warning_level=1',
-      'c_std=c89'
-    ]
-  )
-
-  add_project_arguments('-DVERSION="'+meson.project_version()+'"', language: ['c', 'cpp'])
-
-  cc = meson.get_compiler('c')
-  cxx = meson.get_compiler('cpp')
-endif
-
-
-capi_inc = []
-capi_inc += include_directories('include')
-capi_inc += include_directories('../../gst/nnstreamer/tensor_filter') #TODO remove this
-if not get_option('enable-tizen')
-  capi_inc += include_directories('include/platform')
-endif
-
-capi_main = []
-capi_main += join_paths(meson.current_source_dir(), 'src', 'nnstreamer-capi-pipeline.c')
-capi_main += join_paths(meson.current_source_dir(), 'src', 'nnstreamer-capi-util.c')
-capi_main += join_paths(meson.current_source_dir(), 'src', 'nnstreamer-capi-single.c')
-
-if get_option('enable-tizen')
-  if get_option('enable-tizen-feature-check')
-    capi_main += join_paths(meson.current_source_dir(), 'src', 'nnstreamer-capi-tizen-feature-check.c')
-  endif
-
-  if get_option('enable-tizen-privilege-check')
-    capi_main += join_paths(meson.current_source_dir(), 'src', 'nnstreamer-capi-tizen-privilege-check.c')
-  endif
-endif
-
-capi_devel_main = []
-capi_devel_main += join_paths(meson.current_source_dir(), 'include', 'nnstreamer.h')
-capi_devel_main += join_paths(meson.current_source_dir(), 'include', 'nnstreamer-single.h')
-capi_devel_main += join_paths(meson.current_source_dir(), 'include', 'ml-api-common.h')
-if get_option('enable-tizen')
-  # header for Tizen internal API
-  capi_devel_main += join_paths(meson.current_source_dir(), 'include', 'nnstreamer-tizen-internal.h')
-else
-  capi_devel_main += join_paths(meson.current_source_dir(), 'include', 'platform', 'tizen_error.h')
-endif
-
-# Dependencies
-capi_deps = [
-  nnstreamer_dep, glib_dep, gst_dep, gst_app_dep
-]
-
-if (get_option('enable-tizen'))
-  message('CAPI is in Tizen mode')
-
-  tizen_deps = [
-    dependency('capi-base-common'),
-    dependency('capi-system-info'),
-    dependency('dlog')
-  ]
-
-  if get_option('enable-tizen-privilege-check')
-    tizen_deps += dependency('dpm')
-    tizen_deps += dependency('capi-privacy-privilege-manager')
-    tizen_deps += dependency('mm-camcorder')
-
-    if (tizenVmajor >= 5)
-      tizen_deps += dependency('mm-resource-manager')
-    endif
-  endif
-
-  capi_deps += tizen_deps
-endif
-
-shared_library ('capi-nnstreamer',
-  capi_main,
-  dependencies: capi_deps,
-  include_directories: capi_inc,
-  install: true,
-  install_dir: nnstreamer_libdir,
-  version: meson.project_version(),
-)
-nnstreamer_capi_lib = static_library ('capi-nnstreamer',
-  capi_main,
-  dependencies: capi_deps,
-  include_directories: capi_inc,
-  install: true,
-  install_dir: nnstreamer_libdir,
-)
-
-nnstreamer_capi_dep = declare_dependency(link_with: nnstreamer_capi_lib,
-  dependencies: capi_deps,
-  include_directories: capi_inc,
-)
-
-configure_file(input: 'capi-nnstreamer.pc.in', output: 'capi-nnstreamer.pc',
-  install_dir: join_paths(nnstreamer_libdir, 'pkgconfig'),
-  configuration: nnstreamer_conf
-)
-
-configure_file(input: 'capi-ml-common.pc.in', output: 'capi-ml-common.pc',
-  install_dir: join_paths(nnstreamer_libdir, 'pkgconfig'),
-  configuration: nnstreamer_conf
-)
-
-install_headers(capi_devel_main,
-  subdir: 'nnstreamer'
-)
diff --git a/api/capi/src/README.md b/api/capi/src/README.md
deleted file mode 100644 (file)
index 6446da8..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-# NNStreamer APIs
-
-## Files
-- nnstreamer-capi-pipeline.c - API to make pipeline with NNStreamer
-- nnstreamer-capi-single.c - API to run a single model with NNStreamer, independent of GStreamer
-- nnstreamer-capi-util.c - Utility functions for CAPI
-- tensor\_filter\_single.c - Tensor\_filter independent of GStreamer
-
-## Comparison of Single API
-
-### Latency & Running-time
-Below shows the comparison of old pipeline-based vs Gst-less Single API - showing reduction in latency and running-time for the API (tested with tensorflow-lite).
-
-These values averaged over 10 continuous runs.
-
-|  | Open (us)      | Invoke (ms)           | Close (us)  |
-| --- |:-------------:|:-------------:|:-----:|
-| New (cache warmup) |  658   | 5195 | 206 |
-| Old (cache warmup) |  1228 | 5199   | 5245 |
-| New (no warmup) | 1653 | 5205  | 201 |
-| Old (no warmup) | 7201 | 5225  | 5299  |
-
-
-These values are just for the first run.
-
-| | Open (us)      | Invoke (ms)           | Close (us)  |
-| --- |:-------------:|:-------------:|:-----:|
-| New  |  12326   | 5231 | 2347 |
-| Old |  58772 | 5250   | 52611 |
-
-### Memory consumption
-
-Comparison of the maximum memory consumption between the two API implementations. Both the examples below run the same test case. The difference is that the test case executable has been linked with different API shared library. [mprof](https://github.com/pythonprofilers/memory_profiler) has been used to measure the memory consumption with `--interval 0.01 --include-children` as configuration parameters. The unit test `nnstreamer_capi_singleshot.benchmark_time` was used to compare the memory consumption.
-
-- Old pipeline-based implementation
-![unittest_tizen_capi_single_old](https://user-images.githubusercontent.com/6565775/64155170-3e179200-ce6d-11e9-94d5-b3a4138533c7.png)
-
-- Gst-less implementation
-![unittest_tizen_capi_single_new](https://user-images.githubusercontent.com/6565775/64155182-4374dc80-ce6d-11e9-9d74-660d6261ceb6.png)
diff --git a/api/capi/src/nnstreamer-capi-pipeline.c b/api/capi/src/nnstreamer-capi-pipeline.c
deleted file mode 100644 (file)
index af4e225..0000000
+++ /dev/null
@@ -1,2313 +0,0 @@
-/**
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-capi-pipeline.c
- * @date 11 March 2019
- * @brief NNStreamer/Pipeline(main) C-API Wrapper.
- *        This allows to construct and control NNStreamer pipelines.
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#include <string.h>
-#include <glib.h>
-#include <gst/gstbuffer.h>
-#include <gst/app/app.h>        /* To push data to pipeline */
-
-#include "nnstreamer-capi-private.h"
-#include "tensor_if.h"
-#include "tensor_typedef.h"
-#include "tensor_filter_custom_easy.h"
-#include "nnstreamer_plugin_api.h"
-
-
-#define handle_init(name, h) \
-  ml_pipeline_common_elem *name= (h); \
-  ml_pipeline *p; \
-  ml_pipeline_element *elem; \
-  int ret = ML_ERROR_NONE; \
-  check_feature_state (); \
-  if ((h) == NULL) { \
-    ml_loge ("The given handle is invalid"); \
-    return ML_ERROR_INVALID_PARAMETER; \
-  } \
-\
-  p = name->pipe; \
-  elem = name->element; \
-  if (p == NULL || elem == NULL || p != elem->pipe) { \
-    ml_loge ("The handle appears to be broken."); \
-    return ML_ERROR_INVALID_PARAMETER; \
-  } \
-\
-  g_mutex_lock (&p->lock); \
-  g_mutex_lock (&elem->lock); \
-\
-  if (NULL == g_list_find (elem->handles, name)) { \
-    ml_loge ("The handle does not exists."); \
-    ret = ML_ERROR_INVALID_PARAMETER; \
-    goto unlock_return; \
-  }
-
-#define handle_exit(h) \
-unlock_return: \
-  g_mutex_unlock (&elem->lock); \
-  g_mutex_unlock (&p->lock); \
-  return ret;
-
-/**
- * @brief Internal function to create a referable element in a pipeline
- */
-static ml_pipeline_element *
-construct_element (GstElement * e, ml_pipeline * p, const char *name,
-    ml_pipeline_element_e t)
-{
-  ml_pipeline_element *ret = g_new0 (ml_pipeline_element, 1);
-
-  if (ret == NULL) {
-    ml_loge ("Failed to allocate memory for the pipeline.");
-    return NULL;
-  }
-
-  ret->element = e;
-  ret->pipe = p;
-  ret->name = g_strdup (name);
-  ret->type = t;
-  ret->handles = NULL;
-  ret->src = NULL;
-  ret->sink = NULL;
-  ml_tensors_info_initialize (&ret->tensors_info);
-  ret->size = 0;
-  ret->maxid = 0;
-  ret->handle_id = 0;
-  ret->is_media_stream = FALSE;
-  g_mutex_init (&ret->lock);
-  return ret;
-}
-
-/**
- * @brief Internal function to get the tensors info from the element caps.
- */
-static gboolean
-get_tensors_info_from_caps (GstCaps * caps, ml_tensors_info_s * info)
-{
-  GstStructure *s;
-  GstTensorsConfig config;
-  guint i, n_caps;
-  gboolean found = FALSE;
-
-  ml_tensors_info_initialize (info);
-  n_caps = gst_caps_get_size (caps);
-
-  for (i = 0; i < n_caps; i++) {
-    s = gst_caps_get_structure (caps, i);
-    found = gst_tensors_config_from_structure (&config, s);
-
-    if (found) {
-      ml_tensors_info_copy_from_gst (info, &config.info);
-      break;
-    }
-  }
-
-  return found;
-}
-
-/**
- * @brief Handle a sink element for registered ml_pipeline_sink_cb
- */
-static void
-cb_sink_event (GstElement * e, GstBuffer * b, gpointer user_data)
-{
-  ml_pipeline_element *elem = user_data;
-
-  /** @todo CRITICAL if the pipeline is being killed, don't proceed! */
-
-  GstMemory *mem[ML_TENSOR_SIZE_LIMIT];
-  GstMapInfo info[ML_TENSOR_SIZE_LIMIT];
-  guint i;
-  guint num_mems;
-  GList *l;
-  ml_tensors_data_s *data = NULL;
-  size_t total_size = 0;
-
-  num_mems = gst_buffer_n_memory (b);
-
-  if (num_mems > ML_TENSOR_SIZE_LIMIT) {
-    ml_loge ("Number of memory chunks in a GstBuffer exceed the limit: %u > %u",
-        num_mems, ML_TENSOR_SIZE_LIMIT);
-    return;
-  }
-
-  /* set tensor data */
-  data = g_new0 (ml_tensors_data_s, 1);
-  if (data == NULL) {
-    ml_loge ("Failed to allocate memory for tensors data in sink callback.");
-    return;
-  }
-
-  data->num_tensors = num_mems;
-  for (i = 0; i < num_mems; i++) {
-    mem[i] = gst_buffer_peek_memory (b, i);
-    if (!gst_memory_map (mem[i], &info[i], GST_MAP_READ)) {
-      nns_loge ("Failed to map the output in sink '%s' callback", elem->name);
-      num_mems = i;
-      goto error;
-    }
-
-    data->tensors[i].tensor = info[i].data;
-    data->tensors[i].size = info[i].size;
-
-    total_size += info[i].size;
-  }
-
-  g_mutex_lock (&elem->lock);
-
-  /** @todo This assumes that padcap is static */
-  if (elem->sink == NULL) {
-    /* Get the sink-pad-cap */
-    elem->sink = gst_element_get_static_pad (elem->element, "sink");
-
-    if (elem->sink) {
-      /* sinkpadcap available (negotiated) */
-      GstCaps *caps = gst_pad_get_current_caps (elem->sink);
-
-      if (caps) {
-        gboolean found;
-
-        found = get_tensors_info_from_caps (caps, &elem->tensors_info);
-        gst_caps_unref (caps);
-
-        if (found) {
-          elem->size = 0;
-
-          if (elem->tensors_info.num_tensors != num_mems) {
-            ml_loge
-                ("The sink event of [%s] cannot be handled because the number of tensors mismatches.",
-                elem->name);
-
-            gst_object_unref (elem->sink);
-            elem->sink = NULL;
-            goto error;
-          }
-
-          for (i = 0; i < elem->tensors_info.num_tensors; i++) {
-            size_t sz = ml_tensor_info_get_size (&elem->tensors_info.info[i]);
-
-            /* Not configured, yet. */
-            if (sz == 0)
-              ml_loge ("The caps for sink(%s) is not configured.", elem->name);
-
-            if (sz != data->tensors[i].size) {
-              ml_loge
-                  ("The sink event of [%s] cannot be handled because the tensor dimension mismatches.",
-                  elem->name);
-
-              gst_object_unref (elem->sink);
-              elem->sink = NULL;
-              goto error;
-            }
-
-            elem->size += sz;
-          }
-        } else {
-          gst_object_unref (elem->sink);
-          elem->sink = NULL;    /* It is not valid */
-          goto error;
-          /** @todo What if it keeps being "NULL"? Exception handling at 2nd frame? */
-        }
-      }
-    }
-  }
-
-  /* Get the data! */
-  if (gst_buffer_get_size (b) != total_size ||
-      (elem->size > 0 && total_size != elem->size)) {
-    ml_loge
-        ("The buffersize mismatches. All the three values must be the same: %zu, %zu, %zu",
-        total_size, elem->size, gst_buffer_get_size (b));
-    goto error;
-  }
-
-  /* Iterate e->handles, pass the data to them */
-  for (l = elem->handles; l != NULL; l = l->next) {
-    ml_pipeline_sink_cb callback;
-    ml_pipeline_common_elem *sink = l->data;
-    if (sink->callback_info == NULL)
-      continue;
-
-    callback = sink->callback_info->cb;
-    if (callback)
-      callback (data, &elem->tensors_info, sink->callback_info->pdata);
-
-    /** @todo Measure time. Warn if it takes long. Kill if it takes too long. */
-  }
-
-error:
-  g_mutex_unlock (&elem->lock);
-
-  for (i = 0; i < num_mems; i++) {
-    gst_memory_unmap (mem[i], &info[i]);
-  }
-
-  if (data) {
-    g_free (data);
-    data = NULL;
-  }
-  return;
-}
-
-/**
- * @brief Handle a appsink element for registered ml_pipeline_sink_cb
- */
-static GstFlowReturn
-cb_appsink_new_sample (GstElement * e, gpointer user_data)
-{
-  GstSample *sample;
-  GstBuffer *buffer;
-
-  /* get the sample from appsink */
-  sample = gst_app_sink_pull_sample (GST_APP_SINK (e));
-  buffer = gst_sample_get_buffer (sample);
-
-  cb_sink_event (e, buffer, user_data);
-
-  gst_sample_unref (sample);
-  return GST_FLOW_OK;
-}
-
-/**
- * @brief Callback for bus message.
- */
-static void
-cb_bus_sync_message (GstBus * bus, GstMessage * message, gpointer user_data)
-{
-  ml_pipeline *pipe_h;
-
-  pipe_h = (ml_pipeline *) user_data;
-
-  if (pipe_h == NULL)
-    return;
-
-  switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_EOS:
-      pipe_h->isEOS = TRUE;
-      break;
-    case GST_MESSAGE_STATE_CHANGED:
-      if (GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (pipe_h->element)) {
-        GstState old_state, new_state;
-
-        gst_message_parse_state_changed (message, &old_state, &new_state, NULL);
-        pipe_h->pipe_state = (ml_pipeline_state_e) new_state;
-
-        ml_logd ("The pipeline state changed from %s to %s.",
-            gst_element_state_get_name (old_state),
-            gst_element_state_get_name (new_state));
-
-        if (pipe_h->state_cb.cb) {
-          pipe_h->state_cb.cb (pipe_h->pipe_state, pipe_h->state_cb.user_data);
-        }
-      }
-      break;
-    default:
-      break;
-  }
-}
-
-/**
- * @brief Clean up each element of the pipeline.
- */
-static void
-free_element_handle (gpointer data)
-{
-  ml_pipeline_common_elem *item = (ml_pipeline_common_elem *) data;
-  g_free (item->callback_info);
-  g_free (item);
-}
-
-/**
- * @brief Private function for ml_pipeline_destroy, cleaning up nodes in namednodes
- */
-static void
-cleanup_node (gpointer data)
-{
-  ml_pipeline_element *e = data;
-
-  g_mutex_lock (&e->lock);
-  if (e->type == ML_PIPELINE_ELEMENT_APP_SRC && !e->pipe->isEOS) {
-    int eos_check_cnt = 0;
-
-    /** to push EOS event, the pipeline should be in PLAYING state */
-    gst_element_set_state (e->pipe->element, GST_STATE_PLAYING);
-
-    if (gst_app_src_end_of_stream (GST_APP_SRC (e->element)) != GST_FLOW_OK) {
-      ml_logw ("Failed to set EOS in %s", e->name);
-    }
-    while (!e->pipe->isEOS) {
-      eos_check_cnt++;
-      /** check EOS every 1ms */
-      g_usleep (1000);
-      if (eos_check_cnt >= EOS_MESSAGE_TIME_LIMIT) {
-        ml_loge ("Failed to get EOS message");
-        break;
-      }
-    }
-  }
-
-  g_free (e->name);
-  if (e->src)
-    gst_object_unref (e->src);
-  if (e->sink)
-    gst_object_unref (e->sink);
-
-  /** @todo CRITICAL. Stop the handle callbacks if they are running/ready */
-  if (e->handle_id > 0) {
-    g_signal_handler_disconnect (e->element, e->handle_id);
-    e->handle_id = 0;
-  }
-
-  if (e->handles)
-    g_list_free_full (e->handles, free_element_handle);
-  e->handles = NULL;
-
-  ml_tensors_info_free (&e->tensors_info);
-
-  g_mutex_unlock (&e->lock);
-  g_mutex_clear (&e->lock);
-
-  g_free (e);
-}
-
-/**
- * @brief Private function to release the pipeline resources
- */
-static void
-cleanup_resource (gpointer data)
-{
-  pipeline_resource_s *res = data;
-
-  /* check resource type and free data */
-  if (g_str_has_prefix (res->type, "tizen")) {
-    release_tizen_resource (res->handle, res->type);
-  }
-
-  g_free (res->type);
-  g_free (res);
-}
-
-/**
- * @brief Converts predefined element in pipeline description.
- */
-static int
-convert_element (ml_pipeline_h pipe, const gchar * description, gchar ** result,
-    gboolean is_internal)
-{
-  gchar *converted;
-  int status = ML_ERROR_NONE;
-
-  g_return_val_if_fail (pipe, ML_ERROR_INVALID_PARAMETER);
-  g_return_val_if_fail (description && result, ML_ERROR_INVALID_PARAMETER);
-
-  /* init null */
-  *result = NULL;
-
-  converted = g_strdup (description);
-
-  /* convert pre-defined element for Tizen */
-  status = convert_tizen_element (pipe, &converted, is_internal);
-
-  if (status == ML_ERROR_NONE) {
-    ml_logd ("Converted pipeline: %s", converted);
-    *result = converted;
-  } else {
-    g_free (converted);
-  }
-
-  return status;
-}
-
-/**
- * @brief Iterate elements and prepare element handle.
- */
-static int
-iterate_element (ml_pipeline * pipe_h, GstElement * pipeline,
-    gboolean is_internal)
-{
-  GstIterator *it = NULL;
-  int status = ML_ERROR_NONE;
-
-  g_return_val_if_fail (pipe_h && pipeline, ML_ERROR_INVALID_PARAMETER);
-
-  g_mutex_lock (&pipe_h->lock);
-
-  it = gst_bin_iterate_elements (GST_BIN (pipeline));
-  if (it != NULL) {
-    gboolean done = FALSE;
-    GValue item = G_VALUE_INIT;
-    GObject *obj;
-    gchar *name;
-
-    /* Fill in the hashtable, "namednodes" with named Elements */
-    while (!done) {
-      switch (gst_iterator_next (it, &item)) {
-        case GST_ITERATOR_OK:
-          obj = g_value_get_object (&item);
-
-          if (GST_IS_ELEMENT (obj)) {
-            GstElement *elem = GST_ELEMENT (obj);
-            GstPluginFeature *feature =
-                GST_PLUGIN_FEATURE (gst_element_get_factory (elem));
-            const gchar *plugin_name =
-                gst_plugin_feature_get_plugin_name (feature);
-            const gchar *element_name = gst_plugin_feature_get_name (feature);
-
-            /* validate the availability of the plugin */
-            if (!is_internal && ml_check_plugin_availability (plugin_name,
-                    element_name) != ML_ERROR_NONE) {
-              status = ML_ERROR_NOT_SUPPORTED;
-              done = TRUE;
-              break;
-            }
-
-            name = gst_element_get_name (elem);
-            if (name != NULL) {
-              ml_pipeline_element_e element_type = ML_PIPELINE_ELEMENT_UNKNOWN;
-
-              if (g_str_equal (element_name, "tensor_sink")) {
-                element_type = ML_PIPELINE_ELEMENT_SINK;
-              } else if (g_str_equal (element_name, "appsrc")) {
-                element_type = ML_PIPELINE_ELEMENT_APP_SRC;
-              } else if (g_str_equal (element_name, "appsink")) {
-                element_type = ML_PIPELINE_ELEMENT_APP_SINK;
-              } else if (g_str_equal (element_name, "valve")) {
-                element_type = ML_PIPELINE_ELEMENT_VALVE;
-              } else if (g_str_equal (element_name, "input-selector")) {
-                element_type = ML_PIPELINE_ELEMENT_SWITCH_INPUT;
-              } else if (g_str_equal (element_name, "output-selector")) {
-                element_type = ML_PIPELINE_ELEMENT_SWITCH_OUTPUT;
-              } else {
-                /** @todo CRITICAL HANDLE THIS! */
-              }
-
-              /* check 'sync' property in sink element */
-              if (element_type == ML_PIPELINE_ELEMENT_SINK ||
-                  element_type == ML_PIPELINE_ELEMENT_APP_SINK) {
-                gboolean sync = FALSE;
-
-                g_object_get (G_OBJECT (elem), "sync", &sync, NULL);
-                if (sync) {
-                  ml_logw
-                      ("It is recommended to apply 'sync=false' property to a sink element in most AI applications. Otherwise, inference results of large neural networks will be frequently dropped by the synchronization mechanism at the sink element.");
-                }
-              }
-
-              if (element_type != ML_PIPELINE_ELEMENT_UNKNOWN) {
-                ml_pipeline_element *e;
-
-                e = construct_element (elem, pipe_h, name, element_type);
-                if (e != NULL) {
-                  g_hash_table_insert (pipe_h->namednodes, g_strdup (name), e);
-                } else {
-                  /* allocation failure */
-                  status = ML_ERROR_OUT_OF_MEMORY;
-                  done = TRUE;
-                }
-              }
-
-              g_free (name);
-            }
-          }
-
-          g_value_reset (&item);
-          break;
-        case GST_ITERATOR_RESYNC:
-        case GST_ITERATOR_ERROR:
-          ml_logw
-              ("There is an error or a resync-event while inspecting a pipeline. However, we can still execute the pipeline.");
-          /* fallthrough */
-        case GST_ITERATOR_DONE:
-          done = TRUE;
-      }
-    }
-
-    g_value_unset (&item);
-    /** @todo CRITICAL check the validity of elem=item registered in e */
-    gst_iterator_free (it);
-  }
-
-  g_mutex_unlock (&pipe_h->lock);
-  return status;
-}
-
-/**
- * @brief Internal function to construct the pipeline.
- * If is_internal is true, this will ignore the permission in Tizen.
- */
-static int
-construct_pipeline_internal (const char *pipeline_description,
-    ml_pipeline_state_cb cb, void *user_data, ml_pipeline_h * pipe,
-    gboolean is_internal)
-{
-  GError *err = NULL;
-  GstElement *pipeline;
-  gchar *description = NULL;
-  int status = ML_ERROR_NONE;
-
-  ml_pipeline *pipe_h;
-
-  check_feature_state ();
-
-  if (!pipe || !pipeline_description)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init null */
-  *pipe = NULL;
-
-  if ((status = ml_initialize_gstreamer ()) != ML_ERROR_NONE)
-    return status;
-
-  /* prepare pipeline handle */
-  pipe_h = g_new0 (ml_pipeline, 1);
-  if (pipe_h == NULL) {
-    ml_loge ("Failed to allocate handle for pipeline.");
-    return ML_ERROR_OUT_OF_MEMORY;
-  }
-
-  g_mutex_init (&pipe_h->lock);
-
-  pipe_h->isEOS = FALSE;
-  pipe_h->pipe_state = ML_PIPELINE_STATE_UNKNOWN;
-  pipe_h->namednodes =
-      g_hash_table_new_full (g_str_hash, g_str_equal, g_free, cleanup_node);
-
-  pipe_h->resources =
-      g_hash_table_new_full (g_str_hash, g_str_equal, g_free, cleanup_resource);
-
-  /* convert predefined element and launch the pipeline */
-  status =
-      convert_element ((ml_pipeline_h) pipe_h, pipeline_description,
-      &description, is_internal);
-  if (status != ML_ERROR_NONE)
-    goto failed;
-
-  pipeline = gst_parse_launch (description, &err);
-  g_free (description);
-
-  if (pipeline == NULL || err) {
-    ml_loge ("Cannot parse and launch the given pipeline = [%s], %s",
-        pipeline_description, (err) ? err->message : "unknown reason");
-    g_clear_error (&err);
-
-    if (pipeline)
-      gst_object_unref (pipeline);
-
-    status = ML_ERROR_STREAMS_PIPE;
-    goto failed;
-  }
-
-  g_assert (GST_IS_PIPELINE (pipeline));
-  pipe_h->element = pipeline;
-
-  /* bus and message callback */
-  pipe_h->bus = gst_element_get_bus (pipeline);
-  g_assert (pipe_h->bus);
-
-  gst_bus_enable_sync_message_emission (pipe_h->bus);
-  pipe_h->signal_msg = g_signal_connect (pipe_h->bus, "sync-message",
-      G_CALLBACK (cb_bus_sync_message), pipe_h);
-
-  /* state change callback */
-  pipe_h->state_cb.cb = cb;
-  pipe_h->state_cb.user_data = user_data;
-
-  /* iterate elements and prepare element handle */
-  status = iterate_element (pipe_h, pipeline, is_internal);
-
-  /* finally set pipeline state to PAUSED */
-  if (status == ML_ERROR_NONE) {
-    status = ml_pipeline_stop ((ml_pipeline_h) pipe_h);
-
-    if (status == ML_ERROR_NONE) {
-      /**
-       * Let's wait until the pipeline state is changed to paused.
-       * Otherwise, the following APIs like 'set_property' may incur
-       * unintended behaviors. But, don't need to return any error
-       * even if this state change is not finished within the timeout,
-       * just replying on the caller.
-       */
-      gst_element_get_state (pipeline, NULL, NULL, 10 * GST_MSECOND);
-    }
-  }
-
-failed:
-  if (status != ML_ERROR_NONE) {
-    /* failed to construct the pipeline */
-    ml_pipeline_destroy ((ml_pipeline_h) pipe_h);
-  } else {
-    *pipe = pipe_h;
-  }
-
-  return status;
-}
-
-/**
- * @brief Construct the pipeline (more info in nnstreamer.h)
- */
-int
-ml_pipeline_construct (const char *pipeline_description,
-    ml_pipeline_state_cb cb, void *user_data, ml_pipeline_h * pipe)
-{
-  /* not an internal pipeline construction */
-  return construct_pipeline_internal (pipeline_description, cb, user_data, pipe,
-      FALSE);
-}
-
-#if defined (__TIZEN__)
-/**
- * @brief Construct the pipeline (Tizen internal, see nnstreamer-tizen-internal.h)
- */
-int
-ml_pipeline_construct_internal (const char *pipeline_description,
-    ml_pipeline_state_cb cb, void *user_data, ml_pipeline_h * pipe)
-{
-  /* Tizen internal pipeline construction */
-  return construct_pipeline_internal (pipeline_description, cb, user_data, pipe,
-      TRUE);
-}
-#endif /* __TIZEN__ */
-
-/**
- * @brief Destroy the pipeline (more info in nnstreamer.h)
- */
-int
-ml_pipeline_destroy (ml_pipeline_h pipe)
-{
-  ml_pipeline *p = pipe;
-  GstStateChangeReturn scret;
-  GstState state;
-  guint check_paused_cnt = 0;
-
-  check_feature_state ();
-
-  if (p == NULL)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  g_mutex_lock (&p->lock);
-
-  /* Before changing the state, remove all callbacks. */
-  p->state_cb.cb = NULL;
-
-  g_hash_table_remove_all (p->namednodes);
-  g_hash_table_remove_all (p->resources);
-
-  if (p->element) {
-    /* Pause the pipeline if it's playing */
-    scret = gst_element_get_state (p->element, &state, NULL, 10 * GST_MSECOND); /* 10ms */
-    if (scret != GST_STATE_CHANGE_FAILURE && state == GST_STATE_PLAYING) {
-      scret = gst_element_set_state (p->element, GST_STATE_PAUSED);
-      if (scret == GST_STATE_CHANGE_FAILURE) {
-        g_mutex_unlock (&p->lock);
-        ml_loge
-            ("Failed to wait until state changed PLAYING to PAUSED. For the detail, please check the GStreamer log messages.");
-        return ML_ERROR_STREAMS_PIPE;
-      }
-    }
-
-    g_mutex_unlock (&p->lock);
-    while (p->pipe_state == ML_PIPELINE_STATE_PLAYING) {
-      check_paused_cnt++;
-      /** check PAUSED every 1ms */
-      g_usleep (1000);
-      if (check_paused_cnt >= WAIT_PAUSED_TIME_LIMIT) {
-        ml_loge ("Failed to wait until state changed to PAUSED");
-        break;
-      }
-    }
-    g_mutex_lock (&p->lock);
-
-    /* Stop (NULL State) the pipeline */
-    scret = gst_element_set_state (p->element, GST_STATE_NULL);
-    if (scret != GST_STATE_CHANGE_SUCCESS) {
-      g_mutex_unlock (&p->lock);
-      ml_loge
-          ("Failed to wait until state changed to NULL(STOP). For the detail, please check the GStreamer log messages.");
-      return ML_ERROR_STREAMS_PIPE;
-    }
-
-    if (p->bus) {
-      g_signal_handler_disconnect (p->bus, p->signal_msg);
-      gst_object_unref (p->bus);
-    }
-
-    gst_object_unref (p->element);
-    p->element = NULL;
-  }
-
-  /* Destroy registered callback handles and resources */
-  g_hash_table_destroy (p->namednodes);
-  g_hash_table_destroy (p->resources);
-  p->namednodes = p->resources = NULL;
-
-  g_mutex_unlock (&p->lock);
-  g_mutex_clear (&p->lock);
-
-  g_free (p);
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Get the pipeline state (more info in nnstreamer.h)
- */
-int
-ml_pipeline_get_state (ml_pipeline_h pipe, ml_pipeline_state_e * state)
-{
-  ml_pipeline *p = pipe;
-  GstState _state;
-  GstStateChangeReturn scret;
-
-  check_feature_state ();
-
-  if (p == NULL || state == NULL)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  *state = ML_PIPELINE_STATE_UNKNOWN;
-
-  g_mutex_lock (&p->lock);
-  scret = gst_element_get_state (p->element, &_state, NULL, GST_MSECOND);       /* Do it within 1ms! */
-  g_mutex_unlock (&p->lock);
-
-  if (scret == GST_STATE_CHANGE_FAILURE) {
-    ml_loge
-        ("Failed to get the state of the pipeline. For the detail, please check the GStreamer log messages.");
-    return ML_ERROR_STREAMS_PIPE;
-  }
-
-  *state = (ml_pipeline_state_e) _state;
-  return ML_ERROR_NONE;
-}
-
-/****************************************************
- ** NNStreamer Pipeline Start/Stop Control         **
- ****************************************************/
-/**
- * @brief Start/Resume the pipeline! (more info in nnstreamer.h)
- */
-int
-ml_pipeline_start (ml_pipeline_h pipe)
-{
-  ml_pipeline *p = pipe;
-  GstStateChangeReturn scret;
-  int status = ML_ERROR_NONE;
-
-  check_feature_state ();
-
-  if (p == NULL)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  g_mutex_lock (&p->lock);
-
-  /* check the resources when starting the pipeline */
-  if (g_hash_table_size (p->resources)) {
-    GHashTableIter iter;
-    gpointer key, value;
-
-    /* iterate all handle and acquire res if released */
-    g_hash_table_iter_init (&iter, p->resources);
-    while (g_hash_table_iter_next (&iter, &key, &value)) {
-      if (g_str_has_prefix (key, "tizen")) {
-        status = get_tizen_resource (pipe, key);
-        if (status != ML_ERROR_NONE)
-          goto done;
-      }
-    }
-  }
-
-  scret = gst_element_set_state (p->element, GST_STATE_PLAYING);
-  if (scret == GST_STATE_CHANGE_FAILURE) {
-    ml_loge
-        ("Failed to set the state of the pipeline to PLAYING. For the detail, please check the GStreamer log messages.");
-    status = ML_ERROR_STREAMS_PIPE;
-  }
-
-done:
-  g_mutex_unlock (&p->lock);
-  return status;
-}
-
-/**
- * @brief Pause the pipeline! (more info in nnstreamer.h)
- */
-int
-ml_pipeline_stop (ml_pipeline_h pipe)
-{
-  ml_pipeline *p = pipe;
-  GstStateChangeReturn scret;
-
-  check_feature_state ();
-
-  if (p == NULL)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  g_mutex_lock (&p->lock);
-  scret = gst_element_set_state (p->element, GST_STATE_PAUSED);
-  g_mutex_unlock (&p->lock);
-
-  if (scret == GST_STATE_CHANGE_FAILURE) {
-    ml_loge
-        ("Failed to set the state of the pipeline to PAUSED. For the detail, please check the GStreamer log messages.");
-    return ML_ERROR_STREAMS_PIPE;
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/****************************************************
- ** NNStreamer Pipeline Sink/Src Control           **
- ****************************************************/
-/**
- * @brief Register a callback for sink (more info in nnstreamer.h)
- */
-int
-ml_pipeline_sink_register (ml_pipeline_h pipe, const char *sink_name,
-    ml_pipeline_sink_cb cb, void *user_data, ml_pipeline_sink_h * h)
-{
-  ml_pipeline_element *elem;
-  ml_pipeline *p = pipe;
-  ml_pipeline_common_elem *sink;
-  int ret = ML_ERROR_NONE;
-
-  check_feature_state ();
-
-  if (h == NULL) {
-    ml_loge ("The argument sink handle is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  /* init null */
-  *h = NULL;
-
-  if (pipe == NULL) {
-    ml_loge ("The first argument, pipeline handle is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (sink_name == NULL) {
-    ml_loge ("The second argument, sink name is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (cb == NULL) {
-    ml_loge ("The callback argument, cb, is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  g_mutex_lock (&p->lock);
-  elem = g_hash_table_lookup (p->namednodes, sink_name);
-
-  if (elem == NULL) {
-    ml_loge ("There is no element named [%s] in the pipeline.", sink_name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  if (elem->type != ML_PIPELINE_ELEMENT_SINK &&
-      elem->type != ML_PIPELINE_ELEMENT_APP_SINK) {
-    ml_loge ("The element [%s] in the pipeline is not a sink element.",
-        sink_name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  if (elem->handle_id > 0) {
-    /* no need to connect signal to sink element */
-    ml_logw ("Sink callback is already registered.");
-  } else {
-    /* set callback for new data */
-    if (elem->type == ML_PIPELINE_ELEMENT_SINK) {
-      /* tensor_sink */
-      g_object_set (G_OBJECT (elem->element), "emit-signal", (gboolean) TRUE,
-          NULL);
-      elem->handle_id =
-          g_signal_connect (elem->element, "new-data",
-          G_CALLBACK (cb_sink_event), elem);
-    } else {
-      /* appsink */
-      g_object_set (G_OBJECT (elem->element), "emit-signals", (gboolean) TRUE,
-          NULL);
-      elem->handle_id =
-          g_signal_connect (elem->element, "new-sample",
-          G_CALLBACK (cb_appsink_new_sample), elem);
-    }
-
-    if (elem->handle_id == 0) {
-      ml_loge ("Failed to connect a signal to the element [%s].", sink_name);
-      ret = ML_ERROR_STREAMS_PIPE;
-      goto unlock_return;
-    }
-  }
-
-  sink = g_new0 (ml_pipeline_common_elem, 1);
-  if (sink == NULL) {
-    ml_loge ("Failed to allocate the sink handle for %s.", sink_name);
-    ret = ML_ERROR_OUT_OF_MEMORY;
-    goto unlock_return;
-  }
-
-  sink->callback_info = g_new (callback_info_s, 1);
-  if (sink->callback_info == NULL) {
-    g_free (sink);
-    ml_loge ("Failed to allocate the sink handle for %s.", sink_name);
-    ret = ML_ERROR_OUT_OF_MEMORY;
-    goto unlock_return;
-  }
-
-  sink->pipe = p;
-  sink->element = elem;
-  sink->callback_info->cb = cb;
-  sink->callback_info->pdata = user_data;
-  *h = sink;
-
-  g_mutex_lock (&elem->lock);
-
-  elem->maxid++;
-  sink->id = elem->maxid;
-  elem->handles = g_list_append (elem->handles, sink);
-
-  g_mutex_unlock (&elem->lock);
-
-unlock_return:
-  g_mutex_unlock (&p->lock);
-  return ret;
-}
-
-/**
- * @brief Unregister a callback for sink (more info in nnstreamer.h)
- */
-int
-ml_pipeline_sink_unregister (ml_pipeline_sink_h h)
-{
-  handle_init (sink, h);
-
-  if (elem->handle_id > 0) {
-    g_signal_handler_disconnect (elem->element, elem->handle_id);
-    elem->handle_id = 0;
-  }
-
-  elem->handles = g_list_remove (elem->handles, sink);
-  g_free (sink->callback_info);
-  g_free (sink);
-
-  handle_exit (h);
-}
-
-/**
- * @brief Parse tensors info of src element.
- */
-static int
-ml_pipeline_src_parse_tensors_info (ml_pipeline_element * elem)
-{
-  int ret = ML_ERROR_NONE;
-
-  if (elem->src == NULL) {
-    elem->src = gst_element_get_static_pad (elem->element, "src");
-    elem->size = 0;
-
-    if (elem->src == NULL) {
-      ml_loge
-          ("Failed to get the src pad of the element[%s]. For the detail, please check the GStreamer log messages.",
-          elem->name);
-      ret = ML_ERROR_STREAMS_PIPE;
-    } else {
-      GstCaps *caps = gst_pad_get_allowed_caps (elem->src);
-      guint i;
-      gboolean found = FALSE;
-      size_t sz;
-
-      if (caps) {
-        found = get_tensors_info_from_caps (caps, &elem->tensors_info);
-
-        if (!found && gst_caps_is_fixed (caps)) {
-          GstStructure *caps_s;
-          const gchar *mimetype;
-
-          caps_s = gst_caps_get_structure (caps, 0);
-          mimetype = gst_structure_get_name (caps_s);
-
-          if (!g_str_equal (mimetype, "other/tensor") &&
-              !g_str_equal (mimetype, "other/tensors")) {
-            elem->is_media_stream = TRUE;
-          }
-        }
-
-        gst_caps_unref (caps);
-      }
-
-      if (found) {
-        for (i = 0; i < elem->tensors_info.num_tensors; i++) {
-          sz = ml_tensor_info_get_size (&elem->tensors_info.info[i]);
-          elem->size += sz;
-        }
-      } else {
-        if (!elem->is_media_stream) {
-          ml_logw
-              ("Cannot find caps. The pipeline is not yet negotiated for src element [%s].",
-              elem->name);
-          gst_object_unref (elem->src);
-          elem->src = NULL;
-          ret = ML_ERROR_TRY_AGAIN;
-        }
-      }
-    }
-  }
-
-  return ret;
-}
-
-/**
- * @brief Get a handle to operate a src (more info in nnstreamer.h)
- */
-int
-ml_pipeline_src_get_handle (ml_pipeline_h pipe, const char *src_name,
-    ml_pipeline_src_h * h)
-{
-  ml_pipeline *p = pipe;
-  ml_pipeline_element *elem;
-  ml_pipeline_common_elem *src;
-  int ret = ML_ERROR_NONE;
-
-  check_feature_state ();
-
-  if (h == NULL) {
-    ml_loge ("The argument source handle is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  /* init null */
-  *h = NULL;
-
-  if (pipe == NULL) {
-    ml_loge ("The first argument, pipeline handle is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (src_name == NULL) {
-    ml_loge ("The second argument, source name is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  g_mutex_lock (&p->lock);
-
-  elem = g_hash_table_lookup (p->namednodes, src_name);
-
-  if (elem == NULL) {
-    ml_loge ("There is no element named [%s] in the pipeline.", src_name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  if (elem->type != ML_PIPELINE_ELEMENT_APP_SRC) {
-    ml_loge ("The element [%s] in the pipeline is not a source element.",
-        src_name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  src = *h = g_new0 (ml_pipeline_common_elem, 1);
-  if (src == NULL) {
-    ml_loge ("Failed to allocate the src handle for %s.", src_name);
-    ret = ML_ERROR_OUT_OF_MEMORY;
-    goto unlock_return;
-  }
-
-  src->pipe = p;
-  src->element = elem;
-
-  g_mutex_lock (&elem->lock);
-
-  elem->maxid++;
-  src->id = elem->maxid;
-  elem->handles = g_list_append (elem->handles, src);
-
-  ml_pipeline_src_parse_tensors_info (elem);
-  g_mutex_unlock (&elem->lock);
-
-unlock_return:
-  g_mutex_unlock (&p->lock);
-
-  return ret;
-}
-
-/**
- * @brief Close a src node (more info in nnstreamer.h)
- */
-int
-ml_pipeline_src_release_handle (ml_pipeline_src_h h)
-{
-  handle_init (src, h);
-
-  elem->handles = g_list_remove (elem->handles, src);
-  g_free (src);
-
-  handle_exit (h);
-}
-
-/**
- * @brief Push a data frame to a src (more info in nnstreamer.h)
- */
-int
-ml_pipeline_src_input_data (ml_pipeline_src_h h, ml_tensors_data_h data,
-    ml_pipeline_buf_policy_e policy)
-{
-  GstBuffer *buffer;
-  GstMemory *mem;
-  gpointer mem_data;
-  gsize mem_size;
-  GstFlowReturn gret;
-  ml_tensors_data_s *_data;
-  unsigned int i;
-
-  handle_init (src, h);
-
-  _data = (ml_tensors_data_s *) data;
-  if (!_data) {
-    ml_loge ("The given param data is invalid.");
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  if (_data->num_tensors < 1 || _data->num_tensors > ML_TENSOR_SIZE_LIMIT) {
-    ml_loge ("The tensor size is invalid. It should be 1 ~ %u; where it is %u",
-        ML_TENSOR_SIZE_LIMIT, _data->num_tensors);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto destroy_data;
-  }
-
-  ret = ml_pipeline_src_parse_tensors_info (elem);
-
-  if (ret != ML_ERROR_NONE) {
-    ml_logw
-        ("The pipeline is not ready to accept inputs. The input is ignored.");
-    goto destroy_data;
-  }
-
-  if (!elem->is_media_stream) {
-    if (elem->tensors_info.num_tensors != _data->num_tensors) {
-      ml_loge
-          ("The src push of [%s] cannot be handled because the number of tensors in a frame mismatches. %u != %u",
-          elem->name, elem->tensors_info.num_tensors, _data->num_tensors);
-
-      ret = ML_ERROR_INVALID_PARAMETER;
-      goto destroy_data;
-    }
-
-    for (i = 0; i < elem->tensors_info.num_tensors; i++) {
-      size_t sz = ml_tensor_info_get_size (&elem->tensors_info.info[i]);
-
-      if (sz != _data->tensors[i].size) {
-        ml_loge
-            ("The given input tensor size (%d'th, %zu bytes) mismatches the source pad (%zu bytes)",
-            i, _data->tensors[i].size, sz);
-
-        ret = ML_ERROR_INVALID_PARAMETER;
-        goto destroy_data;
-      }
-    }
-  }
-
-  /* Create buffer to be pushed from buf[] */
-  buffer = gst_buffer_new ();
-  for (i = 0; i < _data->num_tensors; i++) {
-    mem_data = _data->tensors[i].tensor;
-    mem_size = _data->tensors[i].size;
-
-    mem = gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
-        mem_data, mem_size, 0, mem_size, mem_data,
-        (policy == ML_PIPELINE_BUF_POLICY_AUTO_FREE) ? g_free : NULL);
-
-    gst_buffer_append_memory (buffer, mem);
-    /** @todo Verify that gst_buffer_append lists tensors/gstmem in the correct order */
-  }
-
-  /* Push the data! */
-  gret = gst_app_src_push_buffer (GST_APP_SRC (elem->element), buffer);
-
-  /* Free data ptr if buffer policy is auto-free */
-  if (policy == ML_PIPELINE_BUF_POLICY_AUTO_FREE) {
-    g_free (_data);
-    _data = NULL;
-  }
-
-  if (gret == GST_FLOW_FLUSHING) {
-    ml_logw
-        ("The pipeline is not in PAUSED/PLAYING. The input may be ignored.");
-    ret = ML_ERROR_TRY_AGAIN;
-  } else if (gret == GST_FLOW_EOS) {
-    ml_logw ("THe pipeline is in EOS state. The input is ignored.");
-    ret = ML_ERROR_STREAMS_PIPE;
-  }
-
-destroy_data:
-  if (_data != NULL && policy == ML_PIPELINE_BUF_POLICY_AUTO_FREE) {
-    /* Free data handle */
-    ml_tensors_data_destroy (data);
-  }
-
-  handle_exit (h);
-}
-
-/**
- * @brief Gets a handle for the tensors metadata of given src node.
- */
-int
-ml_pipeline_src_get_tensors_info (ml_pipeline_src_h h, ml_tensors_info_h * info)
-{
-  handle_init (src, h);
-
-  if (info == NULL) {
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  ret = ml_pipeline_src_parse_tensors_info (elem);
-
-  if (ret == ML_ERROR_NONE) {
-    ml_tensors_info_create (info);
-    ml_tensors_info_clone (*info, &elem->tensors_info);
-  }
-
-  handle_exit (h);
-}
-
-/****************************************************
- ** NNStreamer Pipeline Switch/Valve Control       **
- ****************************************************/
-
-/**
- * @brief Get a handle to operate a selector (more info in nnstreamer.h)
- */
-int
-ml_pipeline_switch_get_handle (ml_pipeline_h pipe, const char *switch_name,
-    ml_pipeline_switch_e * type, ml_pipeline_switch_h * h)
-{
-  ml_pipeline_element *elem;
-  ml_pipeline *p = pipe;
-  ml_pipeline_common_elem *swtc;
-  int ret = ML_ERROR_NONE;
-
-  check_feature_state ();
-
-  if (h == NULL) {
-    ml_loge ("The argument switch handle is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  /* init null */
-  *h = NULL;
-
-  if (pipe == NULL) {
-    ml_loge ("The first argument, pipeline handle, is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (switch_name == NULL) {
-    ml_loge ("The second argument, switch name, is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  g_mutex_lock (&p->lock);
-  elem = g_hash_table_lookup (p->namednodes, switch_name);
-
-  if (elem == NULL) {
-    ml_loge ("There is no switch element named [%s] in the pipeline.",
-        switch_name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  if (elem->type == ML_PIPELINE_ELEMENT_SWITCH_INPUT) {
-    if (type)
-      *type = ML_PIPELINE_SWITCH_INPUT_SELECTOR;
-  } else if (elem->type == ML_PIPELINE_ELEMENT_SWITCH_OUTPUT) {
-    if (type)
-      *type = ML_PIPELINE_SWITCH_OUTPUT_SELECTOR;
-  } else {
-    ml_loge
-        ("There is an element named [%s] in the pipeline, but it is not an input/output switch",
-        switch_name);
-
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  swtc = *h = g_new0 (ml_pipeline_common_elem, 1);
-  if (swtc == NULL) {
-    ml_loge ("Failed to allocate the switch handle for %s.", switch_name);
-    ret = ML_ERROR_OUT_OF_MEMORY;
-    goto unlock_return;
-  }
-
-  swtc->pipe = p;
-  swtc->element = elem;
-
-  g_mutex_lock (&elem->lock);
-
-  elem->maxid++;
-  swtc->id = elem->maxid;
-  elem->handles = g_list_append (elem->handles, swtc);
-
-  g_mutex_unlock (&elem->lock);
-
-unlock_return:
-  g_mutex_unlock (&p->lock);
-  return ret;
-}
-
-/**
- * @brief Close the given switch handle (more info in nnstreamer.h)
- */
-int
-ml_pipeline_switch_release_handle (ml_pipeline_switch_h h)
-{
-  handle_init (swtc, h);
-
-  elem->handles = g_list_remove (elem->handles, swtc);
-  g_free (swtc);
-
-  handle_exit (h);
-}
-
-/**
- * @brief Control the switch (more info in nnstreamer.h)
- */
-int
-ml_pipeline_switch_select (ml_pipeline_switch_h h, const char *pad_name)
-{
-  GstPad *active_pad, *new_pad;
-  gchar *active_name;
-
-  handle_init (swtc, h);
-
-  if (pad_name == NULL) {
-    ml_loge ("The second argument, pad name, is not valid.");
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  g_object_get (G_OBJECT (elem->element), "active-pad", &active_pad, NULL);
-  active_name = gst_pad_get_name (active_pad);
-
-  if (g_strcmp0 (pad_name, active_name) == 0) {
-    ml_logi ("Switch is called, but there is no effective changes: %s->%s.",
-        active_name, pad_name);
-    g_free (active_name);
-    gst_object_unref (active_pad);
-
-    goto unlock_return;
-  }
-
-  g_free (active_name);
-  gst_object_unref (active_pad);
-
-  new_pad = gst_element_get_static_pad (elem->element, pad_name);
-  if (new_pad == NULL) {
-    /* Not Found! */
-    ml_loge ("Cannot find the pad, [%s], from the switch, [%s].",
-        pad_name, elem->name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  g_object_set (G_OBJECT (elem->element), "active-pad", new_pad, NULL);
-  gst_object_unref (new_pad);
-
-  ml_logi ("Switched to [%s] successfully at switch [%s].", pad_name,
-      elem->name);
-
-  handle_exit (h);
-}
-
-/**
- * @brief Gets the pad names of a switch.
- */
-int
-ml_pipeline_switch_get_pad_list (ml_pipeline_switch_h h, char ***list)
-{
-  GstIterator *it;
-  GValue item = G_VALUE_INIT;
-  gboolean done = FALSE;
-  GList *dllist = NULL;
-  GstPad *pad;
-  int counter = 0;
-
-  handle_init (swtc, h);
-
-  if (list == NULL) {
-    ml_loge ("The second argument, list, is not valid.");
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  /* init null */
-  *list = NULL;
-
-  if (elem->type == ML_PIPELINE_ELEMENT_SWITCH_INPUT)
-    it = gst_element_iterate_sink_pads (elem->element);
-  else if (elem->type == ML_PIPELINE_ELEMENT_SWITCH_OUTPUT)
-    it = gst_element_iterate_src_pads (elem->element);
-  else {
-    ml_loge
-        ("The element, [%s], is supposed to be input/output switch, but it is not. Internal data structure is broken.",
-        elem->name);
-    ret = ML_ERROR_STREAMS_PIPE;
-    goto unlock_return;
-  }
-
-  while (!done) {
-    switch (gst_iterator_next (it, &item)) {
-      case GST_ITERATOR_OK:
-        pad = GST_PAD (g_value_get_object (&item));
-        dllist = g_list_append (dllist, gst_pad_get_name (pad));
-        counter++;
-        g_value_reset (&item);
-        break;
-      case GST_ITERATOR_RESYNC:
-        g_list_free_full (dllist, g_free);      /* This frees all strings as well */
-        dllist = NULL;
-        counter = 0;
-        gst_iterator_resync (it);
-        break;
-      case GST_ITERATOR_ERROR:
-        ml_loge ("Cannot access the list of pad properly of a switch, [%s].",
-            elem->name);
-        ret = ML_ERROR_STREAMS_PIPE;
-        break;
-      case GST_ITERATOR_DONE:
-        done = TRUE;
-        break;
-    }
-  }
-
-  gst_iterator_free (it);
-
-  /* There has been no error with that "while" loop. */
-  if (ret == ML_ERROR_NONE) {
-    int i = 0;
-    GList *l;
-
-    *list = g_malloc0 (sizeof (char *) * (counter + 1));
-    if (*list == NULL) {
-      ml_loge ("Failed to allocate memory for pad list.");
-      ret = ML_ERROR_OUT_OF_MEMORY;
-      goto unlock_return;
-    }
-
-    for (l = dllist; l != NULL; l = l->next) {
-      (*list)[i] = l->data;     /* Allocated by gst_pad_get_name(). Caller has to free it */
-      i++;
-
-      if (i > counter) {
-        g_list_free_full (dllist, g_free);      /* This frees all strings as well */
-        g_free (*list);
-        *list = NULL;
-
-        ml_loge
-            ("Internal data inconsistency. This could be a bug in nnstreamer. Switch [%s].",
-            elem->name);
-        ret = ML_ERROR_STREAMS_PIPE;
-        goto unlock_return;
-      }
-    }
-  }
-  g_list_free (dllist);         /* This does not free the strings.. fortunately. */
-
-  handle_exit (h);
-}
-
-/**
- * @brief Get a handle to operate a Valve (more info in nnstreamer.h)
- */
-int
-ml_pipeline_valve_get_handle (ml_pipeline_h pipe, const char *valve_name,
-    ml_pipeline_valve_h * h)
-{
-  ml_pipeline_element *elem;
-  ml_pipeline *p = pipe;
-  ml_pipeline_common_elem *valve;
-  int ret = ML_ERROR_NONE;
-
-  check_feature_state ();
-
-  if (h == NULL) {
-    ml_loge ("The argument valve handle is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  /* init null */
-  *h = NULL;
-
-  if (pipe == NULL) {
-    ml_loge ("The first argument, pipeline handle, is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (valve_name == NULL) {
-    ml_loge ("The second argument, valve name, is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  g_mutex_lock (&p->lock);
-  elem = g_hash_table_lookup (p->namednodes, valve_name);
-
-  if (elem == NULL) {
-    ml_loge ("There is no valve element named [%s] in the pipeline.",
-        valve_name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  if (elem->type != ML_PIPELINE_ELEMENT_VALVE) {
-    ml_loge
-        ("There is an element named [%s] in the pipeline, but it is not a valve",
-        valve_name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  valve = *h = g_new0 (ml_pipeline_common_elem, 1);
-  if (valve == NULL) {
-    ml_loge ("Failed to allocate the valve handle for %s.", valve_name);
-    ret = ML_ERROR_OUT_OF_MEMORY;
-    goto unlock_return;
-  }
-
-  valve->pipe = p;
-  valve->element = elem;
-
-  g_mutex_lock (&elem->lock);
-
-  elem->maxid++;
-  valve->id = elem->maxid;
-  elem->handles = g_list_append (elem->handles, valve);
-
-  g_mutex_unlock (&elem->lock);
-
-unlock_return:
-  g_mutex_unlock (&p->lock);
-  return ret;
-}
-
-/**
- * @brief Close the given valve handle (more info in nnstreamer.h)
- */
-int
-ml_pipeline_valve_release_handle (ml_pipeline_valve_h h)
-{
-  handle_init (valve, h);
-
-  elem->handles = g_list_remove (elem->handles, valve);
-  g_free (valve);
-
-  handle_exit (h);
-}
-
-/**
- * @brief Control the valve with the given handle (more info in nnstreamer.h)
- */
-int
-ml_pipeline_valve_set_open (ml_pipeline_valve_h h, bool open)
-{
-  gboolean drop = FALSE;
-  handle_init (valve, h);
-
-  g_object_get (G_OBJECT (elem->element), "drop", &drop, NULL);
-
-  if ((open != false) != (drop != FALSE)) {
-    /* Nothing to do */
-    ml_logi ("Valve is called, but there is no effective changes");
-    goto unlock_return;
-  }
-
-  drop = (open) ? FALSE : TRUE;
-  g_object_set (G_OBJECT (elem->element), "drop", drop, NULL);
-
-  handle_exit (h);
-}
-
-/********************************************************
- ** NNStreamer Element Property Control in Pipeline    **
- ********************************************************/
-/**
- * @brief Gets an element handle in NNStreamer pipelines to control its properties.
- */
-int
-ml_pipeline_element_get_handle (ml_pipeline_h pipe, const char *element_name,
-    ml_pipeline_element_h * elem_h)
-{
-  int ret = ML_ERROR_NONE;
-  ml_pipeline_element *elem;
-  ml_pipeline_common_elem *common_elem;
-  ml_pipeline *p = pipe;
-
-  /* Check input parameter */
-  if (pipe == NULL) {
-    ml_loge ("The first argument, pipeline handle, is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (element_name == NULL) {
-    ml_loge ("The second argument, element name, is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (elem_h == NULL) {
-    ml_loge ("The argument element handle is not valid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-  *elem_h = NULL;
-
-  g_mutex_lock (&p->lock);
-
-  /* 1. Search element in lookup table first */
-  elem = g_hash_table_lookup (p->namednodes, element_name);
-  if (elem == NULL) {
-    /* 2. Search element in pipeline itself */
-    GstElement *gst_elem;
-
-    gst_elem = gst_bin_get_by_name (GST_BIN (p->element), element_name);
-    if (gst_elem == NULL) {
-      ml_loge ("The element named [%s] is not found in the pipeline",
-          element_name);
-      ret = ML_ERROR_INVALID_PARAMETER;
-      goto unlock_return;
-    }
-
-    /* Caching for next search */
-    elem = construct_element (gst_elem, pipe, element_name,
-        ML_PIPELINE_ELEMENT_COMMON);
-    if (elem == NULL) {
-      ml_loge ("Failed to allocate the internal memory");
-      ret = ML_ERROR_OUT_OF_MEMORY;
-      goto unlock_return;
-    }
-    g_hash_table_insert (p->namednodes, g_strdup (element_name), elem);
-  }
-
-  /* Type checking */
-  if (elem->type == ML_PIPELINE_ELEMENT_UNKNOWN) {
-    ml_loge
-        ("There is an element named [%s] in the pipeline, but it is unknown type.",
-        element_name);
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  common_elem = *elem_h = g_new0 (ml_pipeline_common_elem, 1);
-  if (common_elem == NULL) {
-    ml_loge ("Failed to allocate the internal handler for %s.", element_name);
-    ret = ML_ERROR_OUT_OF_MEMORY;
-    goto unlock_return;
-  }
-
-  common_elem->pipe = p;
-  common_elem->element = elem;
-
-  g_mutex_lock (&elem->lock);
-  elem->maxid++;
-  common_elem->id = elem->maxid;
-  elem->handles = g_list_append (elem->handles, common_elem);
-  g_mutex_unlock (&elem->lock);
-
-unlock_return:
-  g_mutex_unlock (&p->lock);
-  return ret;
-}
-
-/**
- * @brief Releases the given element handle.
- */
-int
-ml_pipeline_element_release_handle (ml_pipeline_element_h elem_h)
-{
-  handle_init (common_elem, elem_h);
-
-  elem->handles = g_list_remove (elem->handles, common_elem);
-  g_free (common_elem);
-
-  handle_exit (elem_h);
-}
-
-/**
- * @brief Check property existence and its type.
- */
-static bool
-ml_pipeline_element_check_property (GObjectClass * class,
-    const char *property_name, const GType type)
-{
-  GParamSpec *pspec = NULL;
-
-  /* Check property existence */
-  pspec = g_object_class_find_property (class, property_name);
-  if (pspec == NULL) {
-    ml_loge ("The property name [%s] does not exist.", property_name);
-    return FALSE;
-  }
-
-  /* Compare property's type with given type */
-  if (!((pspec->value_type == type) ||
-          (type == G_TYPE_ENUM && G_TYPE_IS_ENUM (pspec->value_type)) ||
-          (type == G_TYPE_INT64 && pspec->value_type == G_TYPE_LONG) ||
-          (type == G_TYPE_UINT64 && pspec->value_type == G_TYPE_ULONG) ||
-          (type == G_TYPE_INT && G_TYPE_IS_ENUM (pspec->value_type)) ||
-          (type == G_TYPE_UINT && G_TYPE_IS_ENUM (pspec->value_type)) ||
-          (type == G_TYPE_DOUBLE && pspec->value_type == G_TYPE_FLOAT))) {
-    ml_loge ("The type of property name [%s] is '%s'", property_name,
-        g_type_name (pspec->value_type));
-    return FALSE;
-  }
-  return TRUE;
-}
-
-/**
- * @brief Sets the value of given element's property in NNStreamer pipelines.
- */
-static int
-ml_pipeline_element_set_property (ml_pipeline_element_h elem_h,
-    const char *property_name, gpointer value, GType type)
-{
-  handle_init (common_elem, elem_h);
-
-  /* Check the input parameter */
-  if (property_name == NULL) {
-    ml_loge ("The second argument, property name is not valid.");
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  /* Check property existence & its type */
-  if (!ml_pipeline_element_check_property (G_OBJECT_GET_CLASS (elem->element),
-          property_name, type)) {
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  /* Set property */
-  if (type == G_TYPE_DOUBLE || type == G_TYPE_FLOAT) {
-    g_object_set (G_OBJECT (elem->element), property_name,
-        *(double *) value, NULL);
-  } else if (type == G_TYPE_INT64) {
-    g_object_set (G_OBJECT (elem->element), property_name,
-        *(int64_t *) value, NULL);
-  } else if (type == G_TYPE_UINT64) {
-    g_object_set (G_OBJECT (elem->element), property_name,
-        *(uint64_t *) value, NULL);
-  } else {
-    g_object_set (G_OBJECT (elem->element), property_name, value, NULL);
-  }
-
-  handle_exit (elem_h);
-}
-
-/**
- * @brief Gets the value of given element's property in NNStreamer pipelines.
- */
-static int
-ml_pipeline_element_get_property (ml_pipeline_element_h elem_h,
-    const char *property_name, GType type, gpointer pvalue)
-{
-  handle_init (common_elem, elem_h);
-
-  /* Check the input parameter */
-  if (property_name == NULL) {
-    ml_loge ("The second argument, property_name is not valid.");
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  if (pvalue == NULL) {
-    ml_loge ("The third argument, value is not valid.");
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  /* Check property existence & its type */
-  if (!ml_pipeline_element_check_property (G_OBJECT_GET_CLASS (elem->element),
-          property_name, type)) {
-    ret = ML_ERROR_INVALID_PARAMETER;
-    goto unlock_return;
-  }
-
-  /* Get property */
-  g_object_get (G_OBJECT (elem->element), property_name, pvalue, NULL);
-
-  handle_exit (elem_h);
-}
-
-/**
- * @brief Sets the boolean value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_set_property_bool (ml_pipeline_element_h elem_h,
-    const char *property_name, const int32_t value)
-{
-  return ml_pipeline_element_set_property (elem_h, property_name,
-      GINT_TO_POINTER (value), G_TYPE_BOOLEAN);
-}
-
-/**
- * @brief Sets the string value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_set_property_string (ml_pipeline_element_h elem_h,
-    const char *property_name, const char *value)
-{
-  return ml_pipeline_element_set_property (elem_h, property_name,
-      (gpointer) value, G_TYPE_STRING);
-}
-
-/**
- * @brief Sets the integer value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_set_property_int32 (ml_pipeline_element_h elem_h,
-    const char *property_name, const int32_t value)
-{
-  return ml_pipeline_element_set_property (elem_h, property_name,
-      GINT_TO_POINTER (value), G_TYPE_INT);
-}
-
-/**
- * @brief Sets the integer 64bit value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_set_property_int64 (ml_pipeline_element_h elem_h,
-    const char *property_name, const int64_t value)
-{
-  return ml_pipeline_element_set_property (elem_h, property_name,
-      (gpointer) (&value), G_TYPE_INT64);
-}
-
-/**
- * @brief Sets the unsigned integer value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_set_property_uint32 (ml_pipeline_element_h elem_h,
-    const char *property_name, const uint32_t value)
-{
-  return ml_pipeline_element_set_property (elem_h, property_name,
-      GUINT_TO_POINTER (value), G_TYPE_UINT);
-}
-
-/**
- * @brief Sets the unsigned integer 64bit value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_set_property_uint64 (ml_pipeline_element_h elem_h,
-    const char *property_name, const uint64_t value)
-{
-  return ml_pipeline_element_set_property (elem_h, property_name,
-      (gpointer) (&value), G_TYPE_UINT64);
-}
-
-/**
- * @brief Sets the floating point value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_set_property_double (ml_pipeline_element_h elem_h,
-    const char *property_name, const double value)
-{
-  return ml_pipeline_element_set_property (elem_h, property_name,
-      (gpointer) (&value), G_TYPE_DOUBLE);
-}
-
-/**
- * @brief Sets the enumeration value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_set_property_enum (ml_pipeline_element_h elem_h,
-    const char *property_name, const uint32_t value)
-{
-  return ml_pipeline_element_set_property (elem_h, property_name,
-      GUINT_TO_POINTER (value), G_TYPE_ENUM);
-}
-
-/**
- * @brief Gets the boolean value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_get_property_bool (ml_pipeline_element_h elem_h,
-    const char *property_name, int32_t * value)
-{
-  return ml_pipeline_element_get_property (elem_h, property_name,
-      G_TYPE_BOOLEAN, (gpointer) value);
-}
-
-/**
- * @brief Gets the string value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_get_property_string (ml_pipeline_element_h elem_h,
-    const char *property_name, char **value)
-{
-  return ml_pipeline_element_get_property (elem_h, property_name,
-      G_TYPE_STRING, (gpointer) value);
-}
-
-/**
- * @brief Gets the integer value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_get_property_int32 (ml_pipeline_element_h elem_h,
-    const char *property_name, int32_t * value)
-{
-  return ml_pipeline_element_get_property (elem_h, property_name,
-      G_TYPE_INT, (gpointer) value);
-}
-
-/**
- * @brief Gets the integer 64bit value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_get_property_int64 (ml_pipeline_element_h elem_h,
-    const char *property_name, int64_t * value)
-{
-  return ml_pipeline_element_get_property (elem_h, property_name,
-      G_TYPE_INT64, (gpointer) value);
-}
-
-/**
- * @brief Gets the unsigned integer value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_get_property_uint32 (ml_pipeline_element_h elem_h,
-    const char *property_name, uint32_t * value)
-{
-  return ml_pipeline_element_get_property (elem_h, property_name,
-      G_TYPE_UINT, (gpointer) value);
-}
-
-/**
- * @brief Gets the unsigned integer 64bit value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_get_property_uint64 (ml_pipeline_element_h elem_h,
-    const char *property_name, uint64_t * value)
-{
-  return ml_pipeline_element_get_property (elem_h, property_name,
-      G_TYPE_UINT64, (gpointer) value);
-}
-
-/**
- * @brief Gets the floating point value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_get_property_double (ml_pipeline_element_h elem_h,
-    const char *property_name, double *value)
-{
-  return ml_pipeline_element_get_property (elem_h, property_name,
-      G_TYPE_DOUBLE, (gpointer) value);
-}
-
-/**
- * @brief Gets the enumeration value of element's property in NNStreamer pipelines.
- */
-int
-ml_pipeline_element_get_property_enum (ml_pipeline_element_h elem_h,
-    const char *property_name, uint32_t * value)
-{
-  return ml_pipeline_element_get_property (elem_h, property_name,
-      G_TYPE_ENUM, (gpointer) value);
-}
-
-/**
- * @brief Gets the element of pipeline itself (GstElement).
- */
-GstElement *
-ml_pipeline_get_gst_element (ml_pipeline_h pipe)
-{
-  ml_pipeline *p = (ml_pipeline *) pipe;
-  GstElement *element = NULL;
-
-  if (p) {
-    g_mutex_lock (&p->lock);
-
-    element = p->element;
-    if (element)
-      gst_object_ref (element);
-
-    g_mutex_unlock (&p->lock);
-  }
-
-  return element;
-}
-
-/**
- * @brief Releases custom filter handle.
- */
-static void
-ml_pipeline_custom_free_handle (ml_custom_filter_s * custom)
-{
-  if (custom) {
-    g_free (custom->name);
-    ml_tensors_info_destroy (custom->in_info);
-    ml_tensors_info_destroy (custom->out_info);
-
-    g_free (custom);
-  }
-}
-
-/**
- * @brief Invoke callback for custom-easy filter.
- */
-static int
-ml_pipeline_custom_invoke (void *data, const GstTensorFilterProperties * prop,
-    const GstTensorMemory * in, GstTensorMemory * out)
-{
-  int status;
-  ml_custom_filter_s *c;
-  ml_tensors_data_h in_data, out_data;
-  ml_tensors_data_s *_data;
-  guint i;
-
-  c = (ml_custom_filter_s *) data;
-  in_data = out_data = NULL;
-
-  /* internal error? */
-  if (!c || !c->cb)
-    return -1;
-
-  /* prepare invoke */
-  status = ml_tensors_data_create_no_alloc (c->in_info, &in_data);
-  if (status != ML_ERROR_NONE)
-    goto done;
-
-  _data = (ml_tensors_data_s *) in_data;
-  for (i = 0; i < _data->num_tensors; i++)
-    _data->tensors[i].tensor = in[i].data;
-
-  status = ml_tensors_data_create_no_alloc (c->out_info, &out_data);
-  if (status != ML_ERROR_NONE)
-    goto done;
-
-  _data = (ml_tensors_data_s *) out_data;
-  for (i = 0; i < _data->num_tensors; i++)
-    _data->tensors[i].tensor = out[i].data;
-
-  /* call invoke callback */
-  status = c->cb (in_data, out_data, c->pdata);
-
-done:
-  /* NOTE: DO NOT free tensor data */
-  g_free (in_data);
-  g_free (out_data);
-
-  return status;
-}
-
-/**
- * @brief Registers a custom filter.
- */
-int
-ml_pipeline_custom_easy_filter_register (const char *name,
-    const ml_tensors_info_h in, const ml_tensors_info_h out,
-    ml_custom_easy_invoke_cb cb, void *user_data,
-    ml_custom_easy_filter_h * custom)
-{
-  int status = ML_ERROR_NONE;
-  ml_custom_filter_s *c;
-  GstTensorsInfo in_info, out_info;
-
-  check_feature_state ();
-
-  if (!name || !cb || !custom)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init null */
-  *custom = NULL;
-
-  if (!ml_tensors_info_is_valid (in) || !ml_tensors_info_is_valid (out))
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* create and init custom handle */
-  if ((c = g_new0 (ml_custom_filter_s, 1)) == NULL)
-    return ML_ERROR_OUT_OF_MEMORY;
-
-  c->name = g_strdup (name);
-  c->cb = cb;
-  c->pdata = user_data;
-  ml_tensors_info_create (&c->in_info);
-  ml_tensors_info_create (&c->out_info);
-
-  ml_tensors_info_clone (c->in_info, in);
-  ml_tensors_info_clone (c->out_info, out);
-
-  /* register custom filter */
-  ml_tensors_info_copy_from_ml (&in_info, in);
-  ml_tensors_info_copy_from_ml (&out_info, out);
-
-  if (NNS_custom_easy_register (name, ml_pipeline_custom_invoke, c,
-          &in_info, &out_info) != 0) {
-    nns_loge ("Failed to register custom filter %s.", name);
-    status = ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (status == ML_ERROR_NONE) {
-    *custom = c;
-  } else {
-    ml_pipeline_custom_free_handle (c);
-  }
-
-  return status;
-}
-
-/**
- * @brief Unregisters the custom filter.
- */
-int
-ml_pipeline_custom_easy_filter_unregister (ml_custom_easy_filter_h custom)
-{
-  ml_custom_filter_s *c;
-
-  check_feature_state ();
-
-  if (!custom)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  c = (ml_custom_filter_s *) custom;
-
-  if (NNS_custom_easy_unregister (c->name) != 0) {
-    ml_loge ("Failed to unregister custom filter %s.", c->name);
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  ml_pipeline_custom_free_handle (c);
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Callback for tensor_if custom condition.
- */
-static gboolean
-ml_pipeline_if_custom (const GstTensorsInfo * info,
-    const GstTensorMemory * input, void *data, gboolean * result)
-{
-  int status = 0;
-  guint i;
-  ml_if_custom_s *c;
-  ml_tensors_data_h in_data;
-  ml_tensors_data_s *_data;
-  ml_tensors_info_h ml_info;
-  GstTensorsInfo in_info = *info;
-  gboolean ret = FALSE;
-
-  c = (ml_if_custom_s *) data;
-  in_data = NULL;
-
-  /* internal error? */
-  if (!c || !c->cb)
-    return FALSE;
-
-  ml_tensors_info_create_from_gst (&ml_info, &in_info);
-  status = ml_tensors_data_create_no_alloc (ml_info, &in_data);
-  if (status != ML_ERROR_NONE)
-    goto done;
-
-  _data = (ml_tensors_data_s *) in_data;
-  for (i = 0; i < _data->num_tensors; i++)
-    _data->tensors[i].tensor = input[i].data;
-
-  /* call invoke callback */
-  status = c->cb (in_data, ml_info, result, c->pdata);
-  if (status == 0)
-    ret = TRUE;
-
-done:
-  ml_tensors_info_destroy (ml_info);
-  g_free (in_data);
-
-  return ret;
-}
-
-/**
- * @brief Releases tensor_if custom condition.
- */
-static void
-ml_pipeline_if_custom_free (ml_if_custom_s * custom)
-{
-  g_free (custom->name);
-  g_free (custom);
-}
-
-/**
- * @brief Registers the tensor_if custom callback.
- */
-int
-ml_pipeline_tensor_if_custom_register (const char *name,
-    ml_pipeline_if_custom_cb cb, void *user_data, ml_pipeline_if_h * if_custom)
-{
-  int status = ML_ERROR_NONE;
-  ml_if_custom_s *c;
-
-  check_feature_state ();
-
-  if (!name || !cb || !if_custom)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init null */
-  *if_custom = NULL;
-
-  /* create and init custom handle */
-  if ((c = g_try_new0 (ml_if_custom_s, 1)) == NULL)
-    return ML_ERROR_OUT_OF_MEMORY;
-
-  c->name = g_strdup (name);
-  c->cb = cb;
-  c->pdata = user_data;
-
-  if (nnstreamer_if_custom_register (name, ml_pipeline_if_custom, c) != 0) {
-    nns_loge ("Failed to register tensor_if custom condition %s.", name);
-    status = ML_ERROR_STREAMS_PIPE;
-  }
-
-  if (status == ML_ERROR_NONE) {
-    *if_custom = c;
-  } else {
-    ml_pipeline_if_custom_free (c);
-  }
-
-  return status;
-}
-
-/**
- * @brief Unregisters the tensor_if custom callback.
- */
-int
-ml_pipeline_tensor_if_custom_unregister (ml_pipeline_if_h if_custom)
-{
-  ml_if_custom_s *c;
-
-  check_feature_state ();
-
-  if (!if_custom)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  c = (ml_if_custom_s *) if_custom;
-
-  if (nnstreamer_if_custom_unregister (c->name) != 0) {
-    ml_loge ("Failed to unregister tensor_if custom condition %s.", c->name);
-    return ML_ERROR_STREAMS_PIPE;
-  }
-
-  ml_pipeline_if_custom_free (c);
-
-  return ML_ERROR_NONE;
-}
diff --git a/api/capi/src/nnstreamer-capi-single.c b/api/capi/src/nnstreamer-capi-single.c
deleted file mode 100644 (file)
index eb27ee0..0000000
+++ /dev/null
@@ -1,1356 +0,0 @@
-/**
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-capi-single.c
- * @date 29 Aug 2019
- * @brief NNStreamer/Single C-API Wrapper.
- *        This allows to invoke individual input frame with NNStreamer.
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @author Parichay Kapoor <pk.kapoor@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#include <nnstreamer-single.h>
-#include <nnstreamer-capi-private.h>
-#include <nnstreamer_plugin_api.h>
-
-#include <tensor_filter_single.h>
-
-#define ML_SINGLE_MAGIC 0xfeedfeed
-
-/**
- * @brief Default time to wait for an output in milliseconds (0 will wait for the output).
- */
-#define SINGLE_DEFAULT_TIMEOUT 0
-
-/**
- * @brief Global lock for single shot API
- * @detail This lock ensures that ml_single_close is thread safe. All other API
- *         functions use the mutex from the single handle. However for close,
- *         single handle mutex cannot be used as single handle is destroyed at
- *         close
- * @note This mutex is automatically initialized as it is statically declared
- */
-G_LOCK_DEFINE_STATIC (magic);
-
-/**
- * @brief Get valid handle after magic verification
- * @note handle's mutex (single_h->mutex) is acquired after this
- * @param[out] single_h The handle properly casted: (ml_single *).
- * @param[in] single The handle to be validated: (void *).
- * @param[in] reset Set TRUE if the handle is to be reset (magic = 0).
- */
-#define ML_SINGLE_GET_VALID_HANDLE_LOCKED(single_h, single, reset) do { \
-  G_LOCK (magic); \
-  single_h = (ml_single *) single; \
-  if (G_UNLIKELY(single_h->magic != ML_SINGLE_MAGIC)) { \
-    ml_loge ("The given param, single is invalid."); \
-    G_UNLOCK (magic); \
-    return ML_ERROR_INVALID_PARAMETER; \
-  } \
-  if (G_UNLIKELY(reset)) \
-    single_h->magic = 0; \
-  g_mutex_lock (&single_h->mutex); \
-  G_UNLOCK (magic); \
-} while (0)
-
-/**
- * @brief This is for the symmetricity with ML_SINGLE_GET_VALID_HANDLE_LOCKED
- * @param[in] single_h The casted handle (ml_single *).
- */
-#define ML_SINGLE_HANDLE_UNLOCK(single_h) g_mutex_unlock (&single_h->mutex);
-
-/** define string names for input/output */
-#define INPUT_STR "input"
-#define OUTPUT_STR "output"
-#define TYPE_STR "type"
-#define NAME_STR "name"
-
-/** concat string from #define */
-#define CONCAT_MACRO_STR(STR1,STR2) STR1 STR2
-
-/** States for invoke thread */
-typedef enum
-{
-  IDLE = 0,           /**< ready to accept next input */
-  RUNNING,            /**< running an input, cannot accept more input */
-  JOIN_REQUESTED      /**< should join the thread, will exit soon */
-} thread_state;
-
-/** ML single api data structure for handle */
-typedef struct
-{
-  GTensorFilterSingleClass *klass;    /**< tensor filter class structure*/
-  GTensorFilterSingle *filter;        /**< tensor filter element */
-  ml_tensors_info_s in_info;          /**< info about input */
-  ml_tensors_info_s out_info;         /**< info about output */
-  ml_nnfw_type_e nnfw;                /**< nnfw type for this filter */
-  guint magic;                        /**< code to verify valid handle */
-
-  GThread *thread;                    /**< thread for invoking */
-  GMutex mutex;                       /**< mutex for synchronization */
-  GCond cond;                         /**< condition for synchronization */
-  ml_tensors_data_h input;            /**< input received from user */
-  ml_tensors_data_h output;           /**< output to be sent back to user */
-  guint timeout;                      /**< timeout for invoking */
-  thread_state state;                 /**< current state of the thread */
-  gboolean ignore_output;             /**< ignore and free the output */
-  gboolean free_output;               /**< true if output tensors are allocated in single-shot */
-  int status;                         /**< status of processing */
-
-  ml_tensors_data_s in_tensors;    /**< input tensor wrapper for processing */
-  ml_tensors_data_s out_tensors;   /**< output tensor wrapper for processing */
-
-  GList *destroy_data_list;         /**< data to be freed by filter */
-} ml_single;
-
-/**
- * @brief setup input and output tensor memory to pass to the tensor_filter.
- * @note this tensor memory wrapper will be reused for each invoke.
- */
-static void
-__setup_in_out_tensors (ml_single * single_h)
-{
-  int i;
-  ml_tensors_data_s *in_tensors = &single_h->in_tensors;
-  ml_tensors_data_s *out_tensors = &single_h->out_tensors;
-
-  /** Setup input buffer */
-  in_tensors->num_tensors = single_h->in_info.num_tensors;
-  for (i = 0; i < single_h->in_info.num_tensors; i++) {
-    /** memory will be allocated by tensor_filter_single */
-    in_tensors->tensors[i].tensor = NULL;
-    in_tensors->tensors[i].size =
-        ml_tensor_info_get_size (&single_h->in_info.info[i]);
-  }
-
-  /** Setup output buffer */
-  out_tensors->num_tensors = single_h->out_info.num_tensors;
-  for (i = 0; i < single_h->out_info.num_tensors; i++) {
-    /** memory will be allocated by tensor_filter_single */
-    out_tensors->tensors[i].tensor = NULL;
-    out_tensors->tensors[i].size =
-        ml_tensor_info_get_size (&single_h->out_info.info[i]);
-  }
-}
-
-/**
- * @brief setup the destroy notify for the allocated output data.
- * @note this stores the data entry in the single list.
- * @note this has not overhead if the allocation of output is not performed by
- * the framework but by tensor filter element.
- */
-static void
-set_destroy_notify (ml_single * single_h, ml_tensors_data_s * data)
-{
-  if (single_h->klass->allocate_in_invoke (single_h->filter)) {
-    data->handle = single_h;
-    single_h->destroy_data_list = g_list_append (single_h->destroy_data_list,
-        (gpointer) data);
-  }
-}
-
-/**
- * @brief To call the framework to destroy the allocated output data
- */
-static inline void
-__destroy_notify (gpointer data_h, gpointer single_data)
-{
-  ml_single *single_h;
-  ml_tensors_data_s *data;
-
-  data = (ml_tensors_data_s *) data_h;
-  single_h = (ml_single *) single_data;
-  if (G_LIKELY (single_h->filter)) {
-    single_h->klass->destroy_notify (single_h->filter,
-        (GstTensorMemory *) data->tensors);
-  }
-  data->handle = NULL;
-}
-
-/**
- * @brief Wrapper function for __destroy_notify
- */
-int
-ml_single_destroy_notify (ml_single_h single, ml_tensors_data_s * data)
-{
-  ml_single *single_h;
-  int status = ML_ERROR_NONE;
-
-  if (G_UNLIKELY (!single || !data))
-    return ML_ERROR_INVALID_PARAMETER;
-
-  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
-
-  if (G_UNLIKELY (!single_h->filter)) {
-    status = ML_ERROR_INVALID_PARAMETER;
-    goto exit;
-  }
-
-  single_h->destroy_data_list =
-      g_list_remove (single_h->destroy_data_list, data);
-  __destroy_notify (data, single_h);
-
-exit:
-  ML_SINGLE_HANDLE_UNLOCK (single_h);
-
-  if (G_UNLIKELY (status != ML_ERROR_NONE))
-    ml_loge ("Failed to destroy the data.");
-  return status;
-}
-
-/**
- * @brief Internal function to call subplugin's invoke
- */
-static inline int
-__invoke (ml_single * single_h)
-{
-  ml_tensors_data_s *in_data, *out_data;
-  int status = ML_ERROR_NONE;
-  GstTensorMemory *in_tensors, *out_tensors;
-
-  in_data = (ml_tensors_data_s *) single_h->input;
-  out_data = (ml_tensors_data_s *) single_h->output;
-
-  in_tensors = (GstTensorMemory *) in_data->tensors;
-  out_tensors = (GstTensorMemory *) out_data->tensors;
-
-  /** invoke the thread */
-  if (!single_h->klass->invoke (single_h->filter, in_tensors, out_tensors,
-          single_h->free_output)) {
-    ml_loge ("Failed to invoke the tensors.");
-    status = ML_ERROR_STREAMS_PIPE;
-    if (single_h->free_output)
-      ml_tensors_data_destroy (single_h->output);
-    single_h->output = NULL;
-  }
-
-  return status;
-}
-
-/**
- * @brief Internal function to post-process given output.
- */
-static inline void
-__process_output (ml_single * single_h)
-{
-  ml_tensors_data_s *out_data;
-
-  if (!single_h->free_output) {
-    /* Do nothing. The output handle is not allocated in single-shot process. */
-    return;
-  }
-
-  if (single_h->ignore_output == TRUE) {
-    /**
-     * Caller of the invoke thread has returned back with timeout
-     * so, free the memory allocated by the invoke as their is no receiver
-     */
-    ml_tensors_data_destroy (single_h->output);
-    single_h->output = NULL;
-  } else {
-    out_data = (ml_tensors_data_s *) single_h->output;
-    set_destroy_notify (single_h, out_data);
-  }
-}
-
-/**
- * @brief thread to execute calls to invoke
- *
- * @details The thread behavior is detailed as below:
- *          - Starting with IDLE state, the thread waits for an input or change
- *          in state externally.
- *          - If state is not RUNNING, exit this thread, else process the
- *          request.
- *          - Process input, call invoke, process output. Any error in this
- *          state sets the status to be used by ml_single_invoke().
- *          - State is set back to IDLE and thread moves back to start.
- *
- *          State changes performed by this function when:
- *          RUNNING -> IDLE - processing is finished.
- *          JOIN_REQUESTED -> IDLE - close is requested.
- *
- * @note Error while processing an input is provided back to requesting
- *       function, and further processing of invoke_thread is not affected.
- */
-static void *
-invoke_thread (void *arg)
-{
-  ml_single *single_h;
-
-  single_h = (ml_single *) arg;
-
-  g_mutex_lock (&single_h->mutex);
-
-  while (single_h->state <= RUNNING) {
-    int status = ML_ERROR_NONE;
-
-    /** wait for data */
-    while (single_h->state != RUNNING) {
-      g_cond_wait (&single_h->cond, &single_h->mutex);
-      if (single_h->state >= JOIN_REQUESTED)
-        goto exit;
-    }
-
-    g_mutex_unlock (&single_h->mutex);
-    status = __invoke (single_h);
-    g_mutex_lock (&single_h->mutex);
-
-    if (status != ML_ERROR_NONE)
-      goto wait_for_next;
-
-    __process_output (single_h);
-
-    /** loop over to wait for the next element */
-  wait_for_next:
-    single_h->status = status;
-    if (single_h->state == RUNNING)
-      single_h->state = IDLE;
-    g_cond_broadcast (&single_h->cond);
-  }
-
-exit:
-  single_h->state = IDLE;
-  g_mutex_unlock (&single_h->mutex);
-  return NULL;
-}
-
-/**
- * @brief Sets the information (tensor dimension, type, name and so on) of required input data for the given model, and get updated output data information.
- * @details Note that a model/framework may not support setting such information.
- * @since_tizen 6.0
- * @param[in] single The model handle.
- * @param[in] in_info The handle of input tensors information.
- * @param[out] out_info The handle of output tensors information. The caller is responsible for freeing the information with ml_tensors_info_destroy().
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful
- * @retval #ML_ERROR_NOT_SUPPORTED This implies that the given framework does not support dynamic dimensions.
- *         Use ml_single_get_input_info() and ml_single_get_output_info() instead for this framework.
- * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
- */
-static int
-ml_single_update_info (ml_single_h single,
-    const ml_tensors_info_h in_info, ml_tensors_info_h * out_info)
-{
-  int status;
-
-  if (!single || !in_info || !out_info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init null */
-  *out_info = NULL;
-
-  status = ml_single_set_input_info (single, in_info);
-  if (status != ML_ERROR_NONE)
-    return status;
-
-  __setup_in_out_tensors (single);
-  return ml_single_get_output_info (single, out_info);
-}
-
-/**
- * @brief Internal function to get the gst info from tensor-filter.
- */
-static void
-ml_single_get_gst_info (ml_single * single_h, gboolean is_input,
-    GstTensorsInfo * gst_info)
-{
-  const gchar *prop_prefix, *prop_name, *prop_type;
-  gchar *val;
-  guint num;
-
-  if (is_input) {
-    prop_prefix = INPUT_STR;
-    prop_type = CONCAT_MACRO_STR (INPUT_STR, TYPE_STR);
-    prop_name = CONCAT_MACRO_STR (INPUT_STR, NAME_STR);
-  } else {
-    prop_prefix = OUTPUT_STR;
-    prop_type = CONCAT_MACRO_STR (OUTPUT_STR, TYPE_STR);
-    prop_name = CONCAT_MACRO_STR (OUTPUT_STR, NAME_STR);
-  }
-
-  gst_tensors_info_init (gst_info);
-
-  /* get dimensions */
-  g_object_get (single_h->filter, prop_prefix, &val, NULL);
-  num = gst_tensors_info_parse_dimensions_string (gst_info, val);
-  g_free (val);
-
-  /* set the number of tensors */
-  gst_info->num_tensors = num;
-
-  /* get types */
-  g_object_get (single_h->filter, prop_type, &val, NULL);
-  num = gst_tensors_info_parse_types_string (gst_info, val);
-  g_free (val);
-
-  if (gst_info->num_tensors != num) {
-    ml_logw ("The number of tensor type is mismatched in filter.");
-  }
-
-  /* get names */
-  g_object_get (single_h->filter, prop_name, &val, NULL);
-  num = gst_tensors_info_parse_names_string (gst_info, val);
-  g_free (val);
-
-  if (gst_info->num_tensors != num) {
-    ml_logw ("The number of tensor name is mismatched in filter.");
-  }
-}
-
-/**
- * @brief Internal function to set the gst info in tensor-filter.
- */
-static int
-ml_single_set_gst_info (ml_single * single_h, const ml_tensors_info_h info)
-{
-  GstTensorsInfo gst_in_info, gst_out_info;
-  int status = ML_ERROR_NONE;
-  int ret = -EINVAL;
-
-  ml_tensors_info_copy_from_ml (&gst_in_info, info);
-
-  ret = single_h->klass->set_input_info (single_h->filter, &gst_in_info,
-      &gst_out_info);
-  if (ret == 0) {
-    ml_tensors_info_copy_from_gst (&single_h->in_info, &gst_in_info);
-    ml_tensors_info_copy_from_gst (&single_h->out_info, &gst_out_info);
-    __setup_in_out_tensors (single_h);
-  } else if (ret == -ENOENT) {
-    status = ML_ERROR_NOT_SUPPORTED;
-  } else {
-    status = ML_ERROR_INVALID_PARAMETER;
-  }
-
-  return status;
-}
-
-/**
- * @brief Set the info for input/output tensors
- */
-static int
-ml_single_set_inout_tensors_info (GObject * object,
-    const gboolean is_input, ml_tensors_info_s * tensors_info)
-{
-  int status = ML_ERROR_NONE;
-  GstTensorsInfo info;
-  gchar *str_dim, *str_type, *str_name;
-  const gchar *str_type_name, *str_name_name;
-  const gchar *prefix;
-
-  if (is_input) {
-    prefix = INPUT_STR;
-    str_type_name = CONCAT_MACRO_STR (INPUT_STR, TYPE_STR);
-    str_name_name = CONCAT_MACRO_STR (INPUT_STR, NAME_STR);
-  } else {
-    prefix = OUTPUT_STR;
-    str_type_name = CONCAT_MACRO_STR (OUTPUT_STR, TYPE_STR);
-    str_name_name = CONCAT_MACRO_STR (OUTPUT_STR, NAME_STR);
-  }
-
-  ml_tensors_info_copy_from_ml (&info, tensors_info);
-
-  /* Set input option */
-  str_dim = gst_tensors_info_get_dimensions_string (&info);
-  str_type = gst_tensors_info_get_types_string (&info);
-  str_name = gst_tensors_info_get_names_string (&info);
-
-  if (!str_dim || !str_type || !str_name || !str_type_name || !str_name_name) {
-    status = ML_ERROR_INVALID_PARAMETER;
-  } else {
-    g_object_set (object, prefix, str_dim, str_type_name, str_type,
-        str_name_name, str_name, NULL);
-  }
-
-  g_free (str_dim);
-  g_free (str_type);
-  g_free (str_name);
-
-  gst_tensors_info_free (&info);
-
-  return status;
-}
-
-/**
- * @brief Internal static function to set tensors info in the handle.
- */
-static gboolean
-ml_single_set_info_in_handle (ml_single_h single, gboolean is_input,
-    ml_tensors_info_s * tensors_info)
-{
-  int status;
-  ml_single *single_h;
-  ml_tensors_info_s *dest;
-  gboolean configured = FALSE;
-  gboolean is_valid = FALSE;
-  GObject *filter_obj;
-
-  single_h = (ml_single *) single;
-  filter_obj = G_OBJECT (single_h->filter);
-
-  if (is_input) {
-    dest = &single_h->in_info;
-    configured = single_h->klass->input_configured (single_h->filter);
-  } else {
-    dest = &single_h->out_info;
-    configured = single_h->klass->output_configured (single_h->filter);
-  }
-
-  if (configured) {
-    /* get configured info and compare with input info */
-    GstTensorsInfo gst_info;
-    ml_tensors_info_h info = NULL;
-
-    ml_single_get_gst_info (single_h, is_input, &gst_info);
-    ml_tensors_info_create_from_gst (&info, &gst_info);
-
-    gst_tensors_info_free (&gst_info);
-
-    if (tensors_info && !ml_tensors_info_is_equal (tensors_info, info)) {
-      /* given input info is not matched with configured */
-      ml_tensors_info_destroy (info);
-      if (is_input) {
-        /* try to update tensors info */
-        status = ml_single_update_info (single, tensors_info, &info);
-        if (status != ML_ERROR_NONE)
-          goto done;
-      } else {
-        goto done;
-      }
-    }
-
-    ml_tensors_info_clone (dest, info);
-    ml_tensors_info_destroy (info);
-  } else if (tensors_info) {
-    status =
-        ml_single_set_inout_tensors_info (filter_obj, is_input, tensors_info);
-    if (status != ML_ERROR_NONE)
-      goto done;
-    ml_tensors_info_clone (dest, tensors_info);
-  }
-
-  is_valid = ml_tensors_info_is_valid (dest);
-
-done:
-  return is_valid;
-}
-
-/**
- * @brief Internal function to create and initialize the single handle.
- */
-static ml_single *
-ml_single_create_handle (ml_nnfw_type_e nnfw)
-{
-  ml_single *single_h;
-  GError *error;
-
-  single_h = g_new0 (ml_single, 1);
-  if (single_h == NULL) {
-    ml_loge ("Failed to allocate the single handle.");
-    return NULL;
-  }
-
-  single_h->filter = g_object_new (G_TYPE_TENSOR_FILTER_SINGLE, NULL);
-  if (single_h->filter == NULL) {
-    ml_loge ("Failed to create a new instance for filter.");
-    g_free (single_h);
-    return NULL;
-  }
-
-  single_h->magic = ML_SINGLE_MAGIC;
-  single_h->timeout = SINGLE_DEFAULT_TIMEOUT;
-  single_h->nnfw = nnfw;
-  single_h->state = IDLE;
-  single_h->ignore_output = FALSE;
-  single_h->thread = NULL;
-  single_h->input = NULL;
-  single_h->output = NULL;
-  single_h->destroy_data_list = NULL;
-
-  ml_tensors_info_initialize (&single_h->in_info);
-  ml_tensors_info_initialize (&single_h->out_info);
-  g_mutex_init (&single_h->mutex);
-  g_cond_init (&single_h->cond);
-
-  single_h->klass = g_type_class_ref (G_TYPE_TENSOR_FILTER_SINGLE);
-  if (single_h->klass == NULL) {
-    ml_loge ("Failed to get class of the filter.");
-    ml_single_close (single_h);
-    return NULL;
-  }
-
-  single_h->thread =
-      g_thread_try_new (NULL, invoke_thread, (gpointer) single_h, &error);
-  if (single_h->thread == NULL) {
-    ml_loge ("Failed to create the invoke thread, error: %s.", error->message);
-    g_clear_error (&error);
-    ml_single_close (single_h);
-    return NULL;
-  }
-
-  return single_h;
-}
-
-/**
- * @brief Validate arguments for open
- */
-static int
-_ml_single_open_custom_validate_arguments (ml_single_h * single,
-    ml_single_preset * info)
-{
-  if (!single) {
-    ml_loge ("The given param is invalid: 'single' is NULL.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-  if (!info) {
-    ml_loge ("The given param is invalid: 'info' is NULL.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  /* Validate input tensor info. */
-  if (info->input_info && !ml_tensors_info_is_valid (info->input_info)) {
-    ml_loge ("The given param, input tensor info is invalid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  /* Validate output tensor info. */
-  if (info->output_info && !ml_tensors_info_is_valid (info->output_info)) {
-    ml_loge ("The given param, output tensor info is invalid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (!info->models) {
-    ml_loge ("The given param, model is invalid: info->models is NULL.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Opens an ML model with the custom options and returns the instance as a handle.
- */
-int
-ml_single_open_custom (ml_single_h * single, ml_single_preset * info)
-{
-  ml_single *single_h;
-  GObject *filter_obj;
-  int status = ML_ERROR_NONE;
-  ml_tensors_info_s *in_tensors_info, *out_tensors_info;
-  ml_nnfw_type_e nnfw;
-  ml_nnfw_hw_e hw;
-  const gchar *fw_name;
-  gchar **list_models;
-  guint num_models;
-  char *hw_name;
-
-  check_feature_state ();
-
-  /* Validate the params */
-  status = _ml_single_open_custom_validate_arguments (single, info);
-  if (ML_ERROR_NONE != status)
-    return status;
-
-  /* init null */
-  *single = NULL;
-
-  in_tensors_info = (ml_tensors_info_s *) info->input_info;
-  out_tensors_info = (ml_tensors_info_s *) info->output_info;
-  nnfw = info->nnfw;
-  hw = info->hw;
-
-  /**
-   * 1. Determine nnfw and validate model file
-   */
-  list_models = g_strsplit (info->models, ",", -1);
-  num_models = g_strv_length (list_models);
-
-  status = ml_validate_model_file ((const char **) list_models, num_models,
-      &nnfw);
-  if (status != ML_ERROR_NONE) {
-    g_strfreev (list_models);
-    return status;
-  }
-
-  g_strfreev (list_models);
-
-  /**
-   * 2. Determine hw
-   * (Supposed CPU only) Support others later.
-   */
-  if (!ml_nnfw_is_available (nnfw, hw)) {
-    ml_loge ("The given nnfw is not available.");
-    return ML_ERROR_NOT_SUPPORTED;
-  }
-
-  /** Create ml_single object */
-  if ((single_h = ml_single_create_handle (nnfw)) == NULL)
-    return ML_ERROR_OUT_OF_MEMORY;
-
-  filter_obj = G_OBJECT (single_h->filter);
-
-  /**
-   * 3. Construct a pipeline
-   * Set the pipeline desc with nnfw.
-   */
-  if (nnfw == ML_NNFW_TYPE_TENSORFLOW || nnfw == ML_NNFW_TYPE_SNAP ||
-      nnfw == ML_NNFW_TYPE_PYTORCH) {
-    /* set input and output tensors information */
-    if (in_tensors_info && out_tensors_info) {
-      status =
-          ml_single_set_inout_tensors_info (filter_obj, TRUE, in_tensors_info);
-      if (status != ML_ERROR_NONE)
-        goto error;
-
-      status =
-          ml_single_set_inout_tensors_info (filter_obj, FALSE,
-          out_tensors_info);
-      if (status != ML_ERROR_NONE)
-        goto error;
-    } else {
-      ml_loge
-          ("To run the pipeline, input and output information should be initialized.");
-      status = ML_ERROR_INVALID_PARAMETER;
-      goto error;
-    }
-  } else if (nnfw == ML_NNFW_TYPE_ARMNN) {
-    /* set input and output tensors information, if available */
-    if (in_tensors_info) {
-      status =
-          ml_single_set_inout_tensors_info (filter_obj, TRUE, in_tensors_info);
-      if (status != ML_ERROR_NONE)
-        goto error;
-    }
-    if (out_tensors_info) {
-      status =
-          ml_single_set_inout_tensors_info (filter_obj, FALSE,
-          out_tensors_info);
-      if (status != ML_ERROR_NONE)
-        goto error;
-    }
-  }
-
-  /* set accelerator, framework, model files and custom option */
-  fw_name = ml_get_nnfw_subplugin_name (nnfw);
-  hw_name = ml_nnfw_to_str_prop (hw);
-  g_object_set (filter_obj, "framework", fw_name, "accelerator", hw_name,
-      "model", info->models, NULL);
-  g_free (hw_name);
-
-  if (info->custom_option) {
-    g_object_set (filter_obj, "custom", info->custom_option, NULL);
-  }
-
-  /* 4. Start the nnfw to get inout configurations if needed */
-  if (!single_h->klass->start (single_h->filter)) {
-    ml_loge ("Failed to start NNFW to get inout configurations.");
-    status = ML_ERROR_STREAMS_PIPE;
-    goto error;
-  }
-
-  /* 5. Set in/out configs and metadata */
-  if (!ml_single_set_info_in_handle (single_h, TRUE, in_tensors_info)) {
-    ml_loge ("The input tensor info is invalid.");
-    status = ML_ERROR_INVALID_PARAMETER;
-    goto error;
-  }
-
-  if (!ml_single_set_info_in_handle (single_h, FALSE, out_tensors_info)) {
-    ml_loge ("The output tensor info is invalid.");
-    status = ML_ERROR_INVALID_PARAMETER;
-    goto error;
-  }
-
-  /* Setup input and output memory buffers for invoke */
-  __setup_in_out_tensors (single_h);
-
-  *single = single_h;
-  return ML_ERROR_NONE;
-
-error:
-  ml_single_close (single_h);
-  return status;
-}
-
-/**
- * @brief Opens an ML model and returns the instance as a handle.
- */
-int
-ml_single_open (ml_single_h * single, const char *model,
-    const ml_tensors_info_h input_info, const ml_tensors_info_h output_info,
-    ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw)
-{
-  return ml_single_open_full (single, model, input_info, output_info, nnfw, hw,
-      NULL);
-}
-
-/**
- * @brief Opens an ML model and returns the instance as a handle.
- */
-int
-ml_single_open_full (ml_single_h * single, const char *model,
-    const ml_tensors_info_h input_info, const ml_tensors_info_h output_info,
-    ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw, const char *custom_option)
-{
-  ml_single_preset info = { 0, };
-
-  info.input_info = input_info;
-  info.output_info = output_info;
-  info.nnfw = nnfw;
-  info.hw = hw;
-  info.models = (char *) model;
-  info.custom_option = (char *) custom_option;
-
-  return ml_single_open_custom (single, &info);
-}
-
-/**
- * @brief Closes the opened model handle.
- *
- * @details State changes performed by this function:
- *          ANY STATE -> JOIN REQUESTED - on receiving a request to close
- *
- *          Once requested to close, invoke_thread() will exit after processing
- *          the current input (if any).
- */
-int
-ml_single_close (ml_single_h single)
-{
-  ml_single *single_h;
-
-  check_feature_state ();
-
-  if (!single) {
-    ml_loge ("The given param, single is invalid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 1);
-
-  single_h->state = JOIN_REQUESTED;
-  g_cond_broadcast (&single_h->cond);
-
-  ML_SINGLE_HANDLE_UNLOCK (single_h);
-
-  if (single_h->thread != NULL)
-    g_thread_join (single_h->thread);
-
-  /** locking ensures correctness with parallel calls on close */
-  if (single_h->filter) {
-    g_list_foreach (single_h->destroy_data_list, __destroy_notify, single_h);
-    g_list_free (single_h->destroy_data_list);
-
-    if (single_h->klass)
-      single_h->klass->stop (single_h->filter);
-
-    gst_object_unref (single_h->filter);
-    single_h->filter = NULL;
-  }
-
-  if (single_h->klass) {
-    g_type_class_unref (single_h->klass);
-    single_h->klass = NULL;
-  }
-
-  ml_tensors_info_free (&single_h->in_info);
-  ml_tensors_info_free (&single_h->out_info);
-
-  g_cond_clear (&single_h->cond);
-  g_mutex_clear (&single_h->mutex);
-
-  g_free (single_h);
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Internal function to validate input/output data.
- */
-static int
-_ml_single_invoke_validate_data (ml_single_h single,
-    const ml_tensors_data_h data, const gboolean is_input)
-{
-  ml_single *single_h;
-  ml_tensors_data_s *_data;
-  ml_tensors_data_s *_model;
-  guint i;
-  size_t raw_size;
-
-  single_h = (ml_single *) single;
-  _data = (ml_tensors_data_s *) data;
-
-  if (G_UNLIKELY (!_data)) {
-    ml_loge ("The data handle to invoke the model is invalid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (is_input)
-    _model = &single_h->in_tensors;
-  else
-    _model = &single_h->out_tensors;
-
-  if (G_UNLIKELY (_data->num_tensors != _model->num_tensors)) {
-    ml_loge
-        ("The number of %s tensors is not compatible with model. Given: %u, Expected: %u.",
-        (is_input) ? "input" : "output", _data->num_tensors,
-        _model->num_tensors);
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  for (i = 0; i < _data->num_tensors; i++) {
-    if (G_UNLIKELY (!_data->tensors[i].tensor)) {
-      ml_loge ("The %d-th input tensor is not valid.", i);
-      return ML_ERROR_INVALID_PARAMETER;
-    }
-
-    raw_size = _model->tensors[i].size;
-    if (G_UNLIKELY (_data->tensors[i].size != raw_size)) {
-      ml_loge
-          ("The size of %d-th %s tensor is not compatible with model. Given: %zu, Expected: %zu (type: %d).",
-          i, (is_input) ? "input" : "output", _data->tensors[i].size, raw_size,
-          single_h->in_info.info[i].type);
-      return ML_ERROR_INVALID_PARAMETER;
-    }
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Internal function to invoke the model.
- *
- * @details State changes performed by this function:
- *          IDLE -> RUNNING - on receiving a valid request
- *
- *          Invoke returns error if the current state is not IDLE.
- *          If IDLE, then invoke is requested to the thread.
- *          Invoke waits for the processing to be complete, and returns back
- *          the result once notified by the processing thread.
- *
- * @note IDLE is the valid thread state before and after this function call.
- */
-static int
-_ml_single_invoke_internal (ml_single_h single,
-    const ml_tensors_data_h input, ml_tensors_data_h * output,
-    const gboolean need_alloc)
-{
-  ml_single *single_h;
-  gint64 end_time;
-  int status = ML_ERROR_NONE;
-
-  check_feature_state ();
-
-  if (G_UNLIKELY (!single)) {
-    ml_loge
-        ("The first argument of ml_single_invoke() is not valid. Please check the single handle.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (G_UNLIKELY (!input)) {
-    ml_loge
-        ("The second argument of ml_single_invoke() is not valid. Please check the input data handle.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (G_UNLIKELY (!output)) {
-    ml_loge
-        ("The third argument of ml_single_invoke() is not valid. Please check the output data handle.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
-
-  if (G_UNLIKELY (!single_h->filter)) {
-    ml_loge
-        ("The tensor_filter element is not valid. It is not correctly created or already freed.");
-    status = ML_ERROR_INVALID_PARAMETER;
-    goto exit;
-  }
-
-  /* Validate input/output data */
-  status = _ml_single_invoke_validate_data (single, input, TRUE);
-  if (status != ML_ERROR_NONE)
-    goto exit;
-
-  if (!need_alloc) {
-    status = _ml_single_invoke_validate_data (single, *output, FALSE);
-    if (status != ML_ERROR_NONE)
-      goto exit;
-  }
-
-  if (single_h->state != IDLE) {
-    if (G_UNLIKELY (single_h->state == JOIN_REQUESTED)) {
-      ml_loge ("The handle is closed or being closed.");
-      status = ML_ERROR_STREAMS_PIPE;
-      goto exit;
-    }
-    ml_loge ("The single invoking thread is not idle.");
-    status = ML_ERROR_TRY_AGAIN;
-    goto exit;
-  }
-
-  /* prepare output data */
-  if (need_alloc) {
-    *output = NULL;
-
-    status = ml_tensors_data_clone_no_alloc (&single_h->out_tensors,
-        &single_h->output);
-    if (status != ML_ERROR_NONE)
-      goto exit;
-  } else {
-    single_h->output = *output;
-  }
-
-  single_h->input = input;
-  single_h->state = RUNNING;
-  single_h->ignore_output = FALSE;
-  single_h->free_output = need_alloc;
-
-  if (single_h->timeout > 0) {
-    /* Wake up "invoke_thread" */
-    g_cond_broadcast (&single_h->cond);
-
-    /* set timeout */
-    end_time = g_get_monotonic_time () +
-        single_h->timeout * G_TIME_SPAN_MILLISECOND;
-
-    if (g_cond_wait_until (&single_h->cond, &single_h->mutex, end_time)) {
-      status = single_h->status;
-    } else {
-      ml_logw ("Wait for invoke has timed out");
-      status = ML_ERROR_TIMED_OUT;
-      /** This is set to notify invoke_thread to not process if timed out */
-      single_h->ignore_output = TRUE;
-    }
-  } else {
-    /**
-     * Don't worry. We have locked single_h->mutex, thus there is no
-     * other thread with ml_single_invoke function on the same handle
-     * that are in this if-then-else block, which means that there is
-     * no other thread with active invoke-thread (calling __invoke())
-     * with the same handle. Thus we can call __invoke without
-     * having yet another mutex for __invoke.
-     */
-    status = __invoke (single_h);
-    if (status != ML_ERROR_NONE)
-      goto exit;
-    __process_output (single_h);
-    single_h->state = IDLE;
-  }
-
-  if (single_h->ignore_output == FALSE) {
-    if (need_alloc)
-      *output = single_h->output;
-    single_h->output = NULL;
-  }
-
-exit:
-  ML_SINGLE_HANDLE_UNLOCK (single_h);
-
-  if (G_UNLIKELY (status != ML_ERROR_NONE))
-    ml_loge ("Failed to invoke the model.");
-  return status;
-}
-
-/**
- * @brief Invokes the model with the given input data.
- */
-int
-ml_single_invoke (ml_single_h single,
-    const ml_tensors_data_h input, ml_tensors_data_h * output)
-{
-  return _ml_single_invoke_internal (single, input, output, TRUE);
-}
-
-/**
- * @brief Invokes the model with the given input data and fills the output data handle.
- */
-int
-ml_single_invoke_fast (ml_single_h single,
-    const ml_tensors_data_h input, ml_tensors_data_h output)
-{
-  return _ml_single_invoke_internal (single, input, &output, FALSE);
-}
-
-/**
- * @brief Gets the tensors info for the given handle.
- */
-static int
-ml_single_get_tensors_info (ml_single_h single, gboolean is_input,
-    ml_tensors_info_h * info)
-{
-  ml_single *single_h;
-  int status = ML_ERROR_NONE;
-  ml_tensors_info_s *input_info;
-
-  check_feature_state ();
-
-  if (!single || !info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
-
-  /* allocate handle for tensors info */
-  status = ml_tensors_info_create (info);
-  if (status != ML_ERROR_NONE)
-    goto exit;
-
-  input_info = (ml_tensors_info_s *) (*info);
-
-  if (is_input)
-    status = ml_tensors_info_clone (input_info, &single_h->in_info);
-  else
-    status = ml_tensors_info_clone (input_info, &single_h->out_info);
-
-  if (status != ML_ERROR_NONE)
-    ml_tensors_info_destroy (input_info);
-
-exit:
-  ML_SINGLE_HANDLE_UNLOCK (single_h);
-  return status;
-}
-
-/**
- * @brief Gets the information of required input data for the given handle.
- * @note information = (tensor dimension, type, name and so on)
- */
-int
-ml_single_get_input_info (ml_single_h single, ml_tensors_info_h * info)
-{
-  return ml_single_get_tensors_info (single, TRUE, info);
-}
-
-/**
- * @brief Gets the information of output data for the given handle.
- * @note information = (tensor dimension, type, name and so on)
- */
-int
-ml_single_get_output_info (ml_single_h single, ml_tensors_info_h * info)
-{
-  return ml_single_get_tensors_info (single, FALSE, info);
-}
-
-/**
- * @brief Sets the maximum amount of time to wait for an output, in milliseconds.
- */
-int
-ml_single_set_timeout (ml_single_h single, unsigned int timeout)
-{
-  ml_single *single_h;
-
-  check_feature_state ();
-
-  if (!single)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
-
-  single_h->timeout = (guint) timeout;
-
-  ML_SINGLE_HANDLE_UNLOCK (single_h);
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Sets the information (tensor dimension, type, name and so on) of required input data for the given model.
- */
-int
-ml_single_set_input_info (ml_single_h single, const ml_tensors_info_h info)
-{
-  ml_single *single_h;
-  int status = ML_ERROR_NONE;
-
-  check_feature_state ();
-
-  if (!single || !info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  if (!ml_tensors_info_is_valid (info))
-    return ML_ERROR_INVALID_PARAMETER;
-
-  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
-  status = ml_single_set_gst_info (single_h, info);
-  ML_SINGLE_HANDLE_UNLOCK (single_h);
-
-  return status;
-}
-
-/**
- * @brief Invokes the model with the given input data with the given info.
- */
-int
-ml_single_invoke_dynamic (ml_single_h single,
-    const ml_tensors_data_h input, const ml_tensors_info_h in_info,
-    ml_tensors_data_h * output, ml_tensors_info_h * out_info)
-{
-  int status;
-  ml_tensors_info_h cur_in_info = NULL;
-
-  if (!single || !input || !in_info || !output || !out_info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init null */
-  *output = NULL;
-  *out_info = NULL;
-
-  status = ml_single_get_input_info (single, &cur_in_info);
-  if (status != ML_ERROR_NONE)
-    goto exit;
-
-  status = ml_single_update_info (single, in_info, out_info);
-  if (status != ML_ERROR_NONE)
-    goto exit;
-
-  status = ml_single_invoke (single, input, output);
-  if (status != ML_ERROR_NONE) {
-    ml_single_set_input_info (single, cur_in_info);
-  }
-
-exit:
-  if (cur_in_info)
-    ml_tensors_info_destroy (cur_in_info);
-
-  if (status != ML_ERROR_NONE) {
-    if (*out_info) {
-      ml_tensors_info_destroy (*out_info);
-      *out_info = NULL;
-    }
-  }
-
-  return status;
-}
-
-/**
- * @brief Sets the property value for the given model.
- */
-int
-ml_single_set_property (ml_single_h single, const char *name, const char *value)
-{
-  ml_single *single_h;
-  int status = ML_ERROR_NONE;
-  char *old_value = NULL;
-
-  check_feature_state ();
-
-  if (!single || !name || !value)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* get old value, also check the property is updatable. */
-  status = ml_single_get_property (single, name, &old_value);
-  if (status != ML_ERROR_NONE)
-    return status;
-
-  /* if sets same value, do not change. */
-  if (old_value != NULL && g_ascii_strcasecmp (old_value, value) == 0) {
-    g_free (old_value);
-    return ML_ERROR_NONE;
-  }
-
-  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
-
-  /* update property */
-  if (g_str_equal (name, "is-updatable")) {
-    /* boolean */
-    if (g_ascii_strcasecmp (value, "true") == 0) {
-      if (g_ascii_strcasecmp (old_value, "true") != 0)
-        g_object_set (G_OBJECT (single_h->filter), name, (gboolean) TRUE, NULL);
-    } else if (g_ascii_strcasecmp (value, "false") == 0) {
-      if (g_ascii_strcasecmp (old_value, "false") != 0)
-        g_object_set (G_OBJECT (single_h->filter), name, (gboolean) FALSE,
-            NULL);
-    } else {
-      ml_loge ("The property value (%s) is not available.", value);
-      status = ML_ERROR_INVALID_PARAMETER;
-    }
-  } else if (g_str_equal (name, "input") || g_str_equal (name, "inputtype")
-      || g_str_equal (name, "inputname") || g_str_equal (name, "output")
-      || g_str_equal (name, "outputtype") || g_str_equal (name, "outputname")) {
-    GstTensorsInfo gst_info;
-    gboolean is_input = g_str_has_prefix (name, "input");
-    guint num;
-
-    ml_single_get_gst_info (single_h, is_input, &gst_info);
-
-    if (g_str_has_suffix (name, "type"))
-      num = gst_tensors_info_parse_types_string (&gst_info, value);
-    else if (g_str_has_suffix (name, "name"))
-      num = gst_tensors_info_parse_names_string (&gst_info, value);
-    else
-      num = gst_tensors_info_parse_dimensions_string (&gst_info, value);
-
-    if (num == gst_info.num_tensors) {
-      ml_tensors_info_h ml_info;
-
-      ml_tensors_info_create_from_gst (&ml_info, &gst_info);
-
-      /* change configuration */
-      status = ml_single_set_gst_info (single_h, ml_info);
-
-      ml_tensors_info_destroy (ml_info);
-    } else {
-      ml_loge ("The property value (%s) is not available.", value);
-      status = ML_ERROR_INVALID_PARAMETER;
-    }
-
-    gst_tensors_info_free (&gst_info);
-  } else {
-    g_object_set (G_OBJECT (single_h->filter), name, value, NULL);
-  }
-
-  ML_SINGLE_HANDLE_UNLOCK (single_h);
-
-  g_free (old_value);
-  return status;
-}
-
-/**
- * @brief Gets the property value for the given model.
- */
-int
-ml_single_get_property (ml_single_h single, const char *name, char **value)
-{
-  ml_single *single_h;
-  int status = ML_ERROR_NONE;
-
-  check_feature_state ();
-
-  if (!single || !name || !value)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init null */
-  *value = NULL;
-
-  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
-
-  if (g_str_equal (name, "input") || g_str_equal (name, "inputtype") ||
-      g_str_equal (name, "inputname") || g_str_equal (name, "inputlayout") ||
-      g_str_equal (name, "output") || g_str_equal (name, "outputtype") ||
-      g_str_equal (name, "outputname") || g_str_equal (name, "outputlayout") ||
-      g_str_equal (name, "accelerator") || g_str_equal (name, "custom")) {
-    /* string */
-    g_object_get (G_OBJECT (single_h->filter), name, value, NULL);
-  } else if (g_str_equal (name, "is-updatable")) {
-    gboolean bool_value = FALSE;
-
-    /* boolean */
-    g_object_get (G_OBJECT (single_h->filter), name, &bool_value, NULL);
-    *value = (bool_value) ? g_strdup ("true") : g_strdup ("false");
-  } else {
-    ml_loge ("The property %s is not available.", name);
-    status = ML_ERROR_NOT_SUPPORTED;
-  }
-
-  ML_SINGLE_HANDLE_UNLOCK (single_h);
-  return status;
-}
diff --git a/api/capi/src/nnstreamer-capi-tizen-feature-check.c b/api/capi/src/nnstreamer-capi-tizen-feature-check.c
deleted file mode 100644 (file)
index 55a9ec9..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-capi-tizen-feature-check.c
- * @date 21 July 2020
- * @brief NNStreamer/C-API Tizen dependent functions.
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#if !defined (__TIZEN__) || !defined (__FEATURE_CHECK_SUPPORT__)
-#error "This file can be included only in Tizen."
-#endif
-
-#include <glib.h>
-#include <system_info.h>
-
-#include "nnstreamer-capi-private.h"
-
-/**
- * @brief Tizen ML feature.
- */
-#define ML_INF_FEATURE_PATH "tizen.org/feature/machine_learning.inference"
-
-/**
- * @brief Internal struct to control tizen feature support (machine_learning.inference).
- * -1: Not checked yet, 0: Not supported, 1: Supported
- */
-typedef struct
-{
-  GMutex mutex;
-  feature_state_t feature_state;
-} feature_info_s;
-
-static feature_info_s *feature_info = NULL;
-
-/**
- * @brief Internal function to initialize feature state.
- */
-static void
-ml_tizen_initialize_feature_state (void)
-{
-  if (feature_info == NULL) {
-    feature_info = g_new0 (feature_info_s, 1);
-    g_assert (feature_info);
-
-    g_mutex_init (&feature_info->mutex);
-    feature_info->feature_state = NOT_CHECKED_YET;
-  }
-}
-
-/**
- * @brief Set the feature status of machine_learning.inference.
- */
-int
-ml_tizen_set_feature_state (int state)
-{
-  ml_tizen_initialize_feature_state ();
-  g_mutex_lock (&feature_info->mutex);
-
-  /**
-   * Update feature status
-   * -1: Not checked yet, 0: Not supported, 1: Supported
-   */
-  feature_info->feature_state = state;
-
-  g_mutex_unlock (&feature_info->mutex);
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Checks whether machine_learning.inference feature is enabled or not.
- */
-int
-ml_tizen_get_feature_enabled (void)
-{
-  int ret;
-  int feature_enabled;
-
-  ml_tizen_initialize_feature_state ();
-
-  g_mutex_lock (&feature_info->mutex);
-  feature_enabled = feature_info->feature_state;
-  g_mutex_unlock (&feature_info->mutex);
-
-  if (NOT_SUPPORTED == feature_enabled) {
-    ml_loge ("machine_learning.inference NOT supported");
-    return ML_ERROR_NOT_SUPPORTED;
-  } else if (NOT_CHECKED_YET == feature_enabled) {
-    bool ml_inf_supported = false;
-    ret =
-        system_info_get_platform_bool (ML_INF_FEATURE_PATH, &ml_inf_supported);
-    if (0 == ret) {
-      if (false == ml_inf_supported) {
-        ml_loge ("machine_learning.inference NOT supported");
-        ml_tizen_set_feature_state (NOT_SUPPORTED);
-        return ML_ERROR_NOT_SUPPORTED;
-      }
-
-      ml_tizen_set_feature_state (SUPPORTED);
-    } else {
-      switch (ret) {
-        case SYSTEM_INFO_ERROR_INVALID_PARAMETER:
-          ml_loge
-              ("failed to get feature value because feature key is not vaild");
-          ret = ML_ERROR_NOT_SUPPORTED;
-          break;
-
-        case SYSTEM_INFO_ERROR_IO_ERROR:
-          ml_loge ("failed to get feature value because of input/output error");
-          ret = ML_ERROR_NOT_SUPPORTED;
-          break;
-
-        case SYSTEM_INFO_ERROR_PERMISSION_DENIED:
-          ml_loge ("failed to get feature value because of permission denied");
-          ret = ML_ERROR_PERMISSION_DENIED;
-          break;
-
-        default:
-          ml_loge ("failed to get feature value because of unknown error");
-          ret = ML_ERROR_NOT_SUPPORTED;
-          break;
-      }
-      return ret;
-    }
-  }
-
-  return ML_ERROR_NONE;
-}
diff --git a/api/capi/src/nnstreamer-capi-tizen-privilege-check.c b/api/capi/src/nnstreamer-capi-tizen-privilege-check.c
deleted file mode 100644 (file)
index 64a69bf..0000000
+++ /dev/null
@@ -1,845 +0,0 @@
-/**
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-capi-tizen-privilege-check.c
- * @date 22 July 2020
- * @brief NNStreamer/C-API Tizen dependent functions.
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#if !defined (__TIZEN__) || !defined (__PRIVILEGE_CHECK_SUPPORT__)
-#error "This file can be included only in Tizen."
-#endif
-
-#include <glib.h>
-
-#include <system_info.h>
-#include <restriction.h>        /* device policy manager */
-#include <privacy_privilege_manager.h>
-#include "nnstreamer-capi-private.h"
-#if TIZEN5PLUS
-#include <mm_resource_manager.h>
-#endif
-#include <mm_camcorder.h>
-
-#include "nnstreamer.h"
-#include "nnstreamer_plugin_api.h"
-
-/* Tizen multimedia framework */
-/* Defined in mm_camcorder_configure.h */
-
-/**
- * @brief Structure to parse ini file for mmfw elements.
- */
-typedef struct _type_int
-{
-  const char *name;
-  int value;
-} type_int;
-
-/**
- * @brief Structure to parse ini file for mmfw elements.
- */
-typedef struct _type_string
-{
-  const char *name;
-  const char *value;
-} type_string;
-
-/**
- * @brief Structure to parse ini file for mmfw elements.
- */
-typedef struct _type_element
-{
-  const char *name;
-  const char *element_name;
-  type_int **value_int;
-  int count_int;
-  type_string **value_string;
-  int count_string;
-} type_element;
-
-/**
- * @brief Structure to parse ini file for mmfw elements.
- */
-typedef struct _conf_detail
-{
-  int count;
-  void **detail_info;
-} conf_detail;
-
-/**
- * @brief Structure to parse ini file for mmfw elements.
- */
-typedef struct _camera_conf
-{
-  int type;
-  conf_detail **info;
-} camera_conf;
-
-#define MMFW_CONFIG_MAIN_FILE "mmfw_camcorder.ini"
-
-extern int
-_mmcamcorder_conf_get_info (MMHandleType handle, int type, const char *ConfFile,
-    camera_conf ** configure_info);
-
-extern void
-_mmcamcorder_conf_release_info (MMHandleType handle,
-    camera_conf ** configure_info);
-
-extern int
-_mmcamcorder_conf_get_element (MMHandleType handle,
-    camera_conf * configure_info, int category, const char *name,
-    type_element ** element);
-
-extern int
-_mmcamcorder_conf_get_value_element_name (type_element * element,
-    const char **value);
-
-/**
- * @brief Internal structure for tizen mm framework.
- */
-typedef struct
-{
-  gboolean invalid; /**< flag to indicate rm handle is valid */
-  mm_resource_manager_h rm_h; /**< rm handle */
-  device_policy_manager_h dpm_h; /**< dpm handle */
-  int dpm_cb_id; /**< dpm callback id */
-  gboolean has_video_src; /**< pipeline includes video src */
-  gboolean has_audio_src; /**< pipeline includes audio src */
-  GHashTable *res_handles; /**< hash table of resource handles */
-} tizen_mm_handle_s;
-
-/**
- * @brief Tizen resouce type for multimedia.
- */
-#define TIZEN_RES_MM "tizen_res_mm"
-
-/**
- * @brief Tizen Privilege Camera (See https://www.tizen.org/privilege)
- */
-#define TIZEN_PRIVILEGE_CAMERA "http://tizen.org/privilege/camera"
-
-/**
- * @brief Tizen Privilege Recoder (See https://www.tizen.org/privilege)
- */
-#define TIZEN_PRIVILEGE_RECODER "http://tizen.org/privilege/recorder"
-
-/** The following functions are either not used or supported in Tizen 4 */
-#if TIZEN5PLUS
-/**
- * @brief Function to check tizen privilege.
- */
-static int
-ml_tizen_check_privilege (const gchar * privilege)
-{
-  int status = ML_ERROR_NONE;
-  ppm_check_result_e priv_result;
-  int err;
-
-  /* check privilege */
-  err = ppm_check_permission (privilege, &priv_result);
-  if (err == PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE &&
-      priv_result == PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW) {
-    /* privilege allowed */
-  } else {
-    ml_loge ("Failed to check the privilege %s.", privilege);
-    status = ML_ERROR_PERMISSION_DENIED;
-  }
-
-  return status;
-}
-
-/**
- * @brief Function to check device policy.
- */
-static int
-ml_tizen_check_dpm_restriction (device_policy_manager_h dpm_handle, int type)
-{
-  int err = DPM_ERROR_NOT_PERMITTED;
-  int dpm_is_allowed = 0;
-
-  switch (type) {
-    case 1:                    /* camera */
-      err = dpm_restriction_get_camera_state (dpm_handle, &dpm_is_allowed);
-      break;
-    case 2:                    /* mic */
-      err = dpm_restriction_get_microphone_state (dpm_handle, &dpm_is_allowed);
-      break;
-    default:
-      /* unknown type */
-      break;
-  }
-
-  if (err != DPM_ERROR_NONE || dpm_is_allowed != 1) {
-    ml_loge ("Failed, device policy is not allowed.");
-    return ML_ERROR_PERMISSION_DENIED;
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Callback to be called when device policy is changed.
- */
-static void
-ml_tizen_dpm_policy_changed_cb (const char *name, const char *state,
-    void *user_data)
-{
-  ml_pipeline *p;
-
-  g_return_if_fail (state);
-  g_return_if_fail (user_data);
-
-  p = (ml_pipeline *) user_data;
-
-  if (g_ascii_strcasecmp (state, "disallowed") == 0) {
-    g_mutex_lock (&p->lock);
-
-    /* pause the pipeline */
-    gst_element_set_state (p->element, GST_STATE_PAUSED);
-
-    g_mutex_unlock (&p->lock);
-  }
-
-  return;
-}
-
-/**
- * @brief Function to get key string of resource type to handle hash table.
- */
-static gchar *
-ml_tizen_mm_res_get_key_string (mm_resource_manager_res_type_e type)
-{
-  gchar *res_key = NULL;
-
-  switch (type) {
-    case MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER:
-      res_key = g_strdup ("tizen_mm_res_video_decoder");
-      break;
-    case MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY:
-      res_key = g_strdup ("tizen_mm_res_video_overlay");
-      break;
-    case MM_RESOURCE_MANAGER_RES_TYPE_CAMERA:
-      res_key = g_strdup ("tizen_mm_res_camera");
-      break;
-    case MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER:
-      res_key = g_strdup ("tizen_mm_res_video_encoder");
-      break;
-    case MM_RESOURCE_MANAGER_RES_TYPE_RADIO:
-      res_key = g_strdup ("tizen_mm_res_radio");
-      break;
-    default:
-      ml_logw ("The resource type %d is invalid.", type);
-      break;
-  }
-
-  return res_key;
-}
-
-/**
- * @brief Function to get resource type from key string to handle hash table.
- */
-static mm_resource_manager_res_type_e
-ml_tizen_mm_res_get_type (const gchar * res_key)
-{
-  mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
-
-  g_return_val_if_fail (res_key, type);
-
-  if (g_str_equal (res_key, "tizen_mm_res_video_decoder")) {
-    type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER;
-  } else if (g_str_equal (res_key, "tizen_mm_res_video_overlay")) {
-    type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_OVERLAY;
-  } else if (g_str_equal (res_key, "tizen_mm_res_camera")) {
-    type = MM_RESOURCE_MANAGER_RES_TYPE_CAMERA;
-  } else if (g_str_equal (res_key, "tizen_mm_res_video_encoder")) {
-    type = MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER;
-  } else if (g_str_equal (res_key, "tizen_mm_res_radio")) {
-    type = MM_RESOURCE_MANAGER_RES_TYPE_RADIO;
-  }
-
-  return type;
-}
-
-/**
- * @brief Callback to be called from mm resource manager.
- */
-static int
-ml_tizen_mm_res_release_cb (mm_resource_manager_h rm,
-    mm_resource_manager_res_h resource_h, void *user_data)
-{
-  ml_pipeline *p;
-  pipeline_resource_s *res;
-  tizen_mm_handle_s *mm_handle;
-
-  g_return_val_if_fail (user_data, FALSE);
-  p = (ml_pipeline *) user_data;
-  g_mutex_lock (&p->lock);
-
-  res =
-      (pipeline_resource_s *) g_hash_table_lookup (p->resources, TIZEN_RES_MM);
-  if (!res) {
-    /* rm handle is not registered or removed */
-    goto done;
-  }
-
-  mm_handle = (tizen_mm_handle_s *) res->handle;
-  if (!mm_handle) {
-    /* supposed the rm handle is already released */
-    goto done;
-  }
-
-  /* pause pipeline */
-  gst_element_set_state (p->element, GST_STATE_PAUSED);
-  mm_handle->invalid = TRUE;
-
-done:
-  g_mutex_unlock (&p->lock);
-  return FALSE;
-}
-
-/**
- * @brief Callback to be called from mm resource manager.
- */
-static void
-ml_tizen_mm_res_status_cb (mm_resource_manager_h rm,
-    mm_resource_manager_status_e status, void *user_data)
-{
-  ml_pipeline *p;
-  pipeline_resource_s *res;
-  tizen_mm_handle_s *mm_handle;
-
-  g_return_if_fail (user_data);
-
-  p = (ml_pipeline *) user_data;
-  g_mutex_lock (&p->lock);
-
-  res =
-      (pipeline_resource_s *) g_hash_table_lookup (p->resources, TIZEN_RES_MM);
-  if (!res) {
-    /* rm handle is not registered or removed */
-    goto done;
-  }
-
-  mm_handle = (tizen_mm_handle_s *) res->handle;
-  if (!mm_handle) {
-    /* supposed the rm handle is already released */
-    goto done;
-  }
-
-  switch (status) {
-    case MM_RESOURCE_MANAGER_STATUS_DISCONNECTED:
-      /* pause pipeline, rm handle should be released */
-      gst_element_set_state (p->element, GST_STATE_PAUSED);
-      mm_handle->invalid = TRUE;
-      break;
-    default:
-      break;
-  }
-
-done:
-  g_mutex_unlock (&p->lock);
-}
-
-/**
- * @brief Function to get the handle of resource type.
- */
-static int
-ml_tizen_mm_res_get_handle (mm_resource_manager_h rm,
-    mm_resource_manager_res_type_e res_type, gpointer * handle)
-{
-  mm_resource_manager_res_h rm_res_h;
-  int status = ML_ERROR_STREAMS_PIPE;
-  int err;
-
-  /* add resource handle */
-  err = mm_resource_manager_mark_for_acquire (rm, res_type,
-      MM_RESOURCE_MANAGER_RES_VOLUME_FULL, &rm_res_h);
-  if (err != MM_RESOURCE_MANAGER_ERROR_NONE)
-    goto rm_error;
-
-  err = mm_resource_manager_commit (rm);
-  if (err != MM_RESOURCE_MANAGER_ERROR_NONE)
-    goto rm_error;
-
-  *handle = rm_res_h;
-  status = ML_ERROR_NONE;
-
-rm_error:
-  return status;
-}
-
-/**
- * @brief Function to release the resource handle of tizen mm resource manager.
- */
-static void
-ml_tizen_mm_res_release (gpointer handle, gboolean destroy)
-{
-  tizen_mm_handle_s *mm_handle;
-
-  g_return_if_fail (handle);
-
-  mm_handle = (tizen_mm_handle_s *) handle;
-
-  /* release res handles */
-  if (g_hash_table_size (mm_handle->res_handles)) {
-    GHashTableIter iter;
-    gpointer key, value;
-    gboolean marked = FALSE;
-
-    g_hash_table_iter_init (&iter, mm_handle->res_handles);
-    while (g_hash_table_iter_next (&iter, &key, &value)) {
-      pipeline_resource_s *mm_res = value;
-
-      if (mm_res->handle) {
-        mm_resource_manager_mark_for_release (mm_handle->rm_h, mm_res->handle);
-        mm_res->handle = NULL;
-        marked = TRUE;
-      }
-
-      if (destroy)
-        g_free (mm_res->type);
-    }
-
-    if (marked)
-      mm_resource_manager_commit (mm_handle->rm_h);
-  }
-
-  mm_resource_manager_set_status_cb (mm_handle->rm_h, NULL, NULL);
-  mm_resource_manager_destroy (mm_handle->rm_h);
-  mm_handle->rm_h = NULL;
-
-  mm_handle->invalid = FALSE;
-
-  if (destroy) {
-    if (mm_handle->dpm_h) {
-      if (mm_handle->dpm_cb_id > 0) {
-        dpm_remove_policy_changed_cb (mm_handle->dpm_h, mm_handle->dpm_cb_id);
-        mm_handle->dpm_cb_id = 0;
-      }
-
-      dpm_manager_destroy (mm_handle->dpm_h);
-      mm_handle->dpm_h = NULL;
-    }
-
-    g_hash_table_remove_all (mm_handle->res_handles);
-    g_free (mm_handle);
-  }
-}
-
-/**
- * @brief Function to initialize mm resource manager.
- */
-static int
-ml_tizen_mm_res_initialize (ml_pipeline_h pipe, gboolean has_video_src,
-    gboolean has_audio_src)
-{
-  ml_pipeline *p;
-  pipeline_resource_s *res;
-  tizen_mm_handle_s *mm_handle = NULL;
-  int status = ML_ERROR_STREAMS_PIPE;
-
-  p = (ml_pipeline *) pipe;
-
-  res =
-      (pipeline_resource_s *) g_hash_table_lookup (p->resources, TIZEN_RES_MM);
-
-  /* register new resource handle of tizen mmfw */
-  if (!res) {
-    res = g_new0 (pipeline_resource_s, 1);
-    if (!res) {
-      ml_loge ("Failed to allocate pipeline resource handle.");
-      status = ML_ERROR_OUT_OF_MEMORY;
-      goto rm_error;
-    }
-
-    res->type = g_strdup (TIZEN_RES_MM);
-    g_hash_table_insert (p->resources, g_strdup (TIZEN_RES_MM), res);
-  }
-
-  mm_handle = (tizen_mm_handle_s *) res->handle;
-  if (!mm_handle) {
-    mm_handle = g_new0 (tizen_mm_handle_s, 1);
-    if (!mm_handle) {
-      ml_loge ("Failed to allocate media resource handle.");
-      status = ML_ERROR_OUT_OF_MEMORY;
-      goto rm_error;
-    }
-
-    mm_handle->res_handles =
-        g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-    /* device policy manager */
-    mm_handle->dpm_h = dpm_manager_create ();
-    if (dpm_add_policy_changed_cb (mm_handle->dpm_h, "camera",
-            ml_tizen_dpm_policy_changed_cb, pipe,
-            &mm_handle->dpm_cb_id) != DPM_ERROR_NONE) {
-      ml_loge ("Failed to add device policy callback.");
-      status = ML_ERROR_PERMISSION_DENIED;
-      goto rm_error;
-    }
-
-    /* set mm handle */
-    res->handle = mm_handle;
-  }
-
-  mm_handle->has_video_src = has_video_src;
-  mm_handle->has_audio_src = has_audio_src;
-  status = ML_ERROR_NONE;
-
-rm_error:
-  if (status != ML_ERROR_NONE) {
-    /* failed to initialize mm handle */
-    if (mm_handle)
-      ml_tizen_mm_res_release (mm_handle, TRUE);
-  }
-
-  return status;
-}
-
-/**
- * @brief Function to acquire the resource from mm resource manager.
- */
-static int
-ml_tizen_mm_res_acquire (ml_pipeline_h pipe,
-    mm_resource_manager_res_type_e res_type)
-{
-  ml_pipeline *p;
-  pipeline_resource_s *res;
-  tizen_mm_handle_s *mm_handle;
-  gchar *res_key;
-  int status = ML_ERROR_STREAMS_PIPE;
-  int err;
-
-  p = (ml_pipeline *) pipe;
-
-  res =
-      (pipeline_resource_s *) g_hash_table_lookup (p->resources, TIZEN_RES_MM);
-  if (!res)
-    goto rm_error;
-
-  mm_handle = (tizen_mm_handle_s *) res->handle;
-  if (!mm_handle)
-    goto rm_error;
-
-  /* check dpm state */
-  if (mm_handle->has_video_src &&
-      (status =
-          ml_tizen_check_dpm_restriction (mm_handle->dpm_h,
-              1)) != ML_ERROR_NONE) {
-    goto rm_error;
-  }
-
-  if (mm_handle->has_audio_src &&
-      (status =
-          ml_tizen_check_dpm_restriction (mm_handle->dpm_h,
-              2)) != ML_ERROR_NONE) {
-    goto rm_error;
-  }
-
-  /* check invalid handle */
-  if (mm_handle->invalid)
-    ml_tizen_mm_res_release (mm_handle, FALSE);
-
-  /* create rm handle */
-  if (!mm_handle->rm_h) {
-    mm_resource_manager_h rm_h;
-
-    err = mm_resource_manager_create (MM_RESOURCE_MANAGER_APP_CLASS_MEDIA,
-        ml_tizen_mm_res_release_cb, pipe, &rm_h);
-    if (err != MM_RESOURCE_MANAGER_ERROR_NONE)
-      goto rm_error;
-
-    /* add state change callback */
-    err =
-        mm_resource_manager_set_status_cb (rm_h, ml_tizen_mm_res_status_cb,
-        pipe);
-    if (err != MM_RESOURCE_MANAGER_ERROR_NONE) {
-      mm_resource_manager_destroy (rm_h);
-      goto rm_error;
-    }
-
-    mm_handle->rm_h = rm_h;
-  }
-
-  /* acquire resource */
-  if (res_type == MM_RESOURCE_MANAGER_RES_TYPE_MAX) {
-    GHashTableIter iter;
-    gpointer key, value;
-
-    /* iterate all handle and acquire res if released */
-    g_hash_table_iter_init (&iter, mm_handle->res_handles);
-    while (g_hash_table_iter_next (&iter, &key, &value)) {
-      pipeline_resource_s *mm_res = value;
-
-      if (!mm_res->handle) {
-        mm_resource_manager_res_type_e type;
-
-        type = ml_tizen_mm_res_get_type (mm_res->type);
-        if (type != MM_RESOURCE_MANAGER_RES_TYPE_MAX) {
-          status =
-              ml_tizen_mm_res_get_handle (mm_handle->rm_h, type,
-              &mm_res->handle);
-          if (status != ML_ERROR_NONE)
-            goto rm_error;
-        }
-      }
-    }
-  } else {
-    res_key = ml_tizen_mm_res_get_key_string (res_type);
-    if (res_key) {
-      pipeline_resource_s *mm_res;
-
-      mm_res =
-          (pipeline_resource_s *) g_hash_table_lookup (mm_handle->res_handles,
-          res_key);
-      if (!mm_res) {
-        mm_res = g_new0 (pipeline_resource_s, 1);
-        if (mm_res == NULL) {
-          ml_loge ("Failed to allocate media resource data.");
-          g_free (res_key);
-          status = ML_ERROR_OUT_OF_MEMORY;
-          goto rm_error;
-        }
-
-        mm_res->type = g_strdup (res_key);
-        g_hash_table_insert (mm_handle->res_handles, g_strdup (res_key),
-            mm_res);
-      }
-
-      g_free (res_key);
-
-      if (!mm_res->handle) {
-        status =
-            ml_tizen_mm_res_get_handle (mm_handle->rm_h, res_type,
-            &mm_res->handle);
-        if (status != ML_ERROR_NONE)
-          goto rm_error;
-      }
-    }
-  }
-
-  /* done */
-  status = ML_ERROR_NONE;
-
-rm_error:
-  return status;
-}
-
-/**
- * @brief Gets element name from mm conf and replaces element.
- */
-static int
-ml_tizen_mm_replace_element (MMHandleType * handle, camera_conf * conf,
-    gint category, const gchar * name, const gchar * what, gchar ** description)
-{
-  type_element *element = NULL;
-  const gchar *src_name = NULL;
-  guint changed = 0;
-
-  _mmcamcorder_conf_get_element (handle, conf, category, name, &element);
-  _mmcamcorder_conf_get_value_element_name (element, &src_name);
-
-  if (!src_name) {
-    ml_loge ("Failed to get the name of %s.", name);
-    return ML_ERROR_STREAMS_PIPE;
-  }
-
-  *description = replace_string (*description, what, src_name, " !", &changed);
-  if (changed > 1) {
-    /* allow one src in the pipeline */
-    ml_loge ("Cannot parse duplicated src node.");
-    return ML_ERROR_STREAMS_PIPE;
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Converts predefined mmfw element.
- */
-static int
-ml_tizen_mm_convert_element (ml_pipeline_h pipe, gchar ** result,
-    gboolean is_internal)
-{
-  gchar *video_src, *audio_src;
-  MMHandleType hcam = NULL;
-  MMCamPreset cam_info;
-  camera_conf *cam_conf = NULL;
-  int status = ML_ERROR_STREAMS_PIPE;
-  int err;
-
-  video_src = g_strstr_len (*result, -1, ML_TIZEN_CAM_VIDEO_SRC);
-  audio_src = g_strstr_len (*result, -1, ML_TIZEN_CAM_AUDIO_SRC);
-
-  /* replace src element */
-  if (video_src || audio_src) {
-    /* check privilege first */
-    if (!is_internal) {
-      /* ignore permission when runs as internal mode */
-      if (video_src &&
-          (status =
-              ml_tizen_check_privilege (TIZEN_PRIVILEGE_CAMERA)) !=
-          ML_ERROR_NONE) {
-        goto mm_error;
-      }
-
-      if (audio_src &&
-          (status =
-              ml_tizen_check_privilege (TIZEN_PRIVILEGE_RECODER)) !=
-          ML_ERROR_NONE) {
-        goto mm_error;
-      }
-    }
-
-    /* create camcoder handle (primary camera) */
-    if (video_src) {
-      cam_info.videodev_type = MM_VIDEO_DEVICE_CAMERA0;
-    } else {
-      /* no camera */
-      cam_info.videodev_type = MM_VIDEO_DEVICE_NONE;
-    }
-
-    if ((err = mm_camcorder_create (&hcam, &cam_info)) != MM_ERROR_NONE) {
-      ml_loge ("Fail to call mm_camcorder_create = %x\n", err);
-      goto mm_error;
-    }
-
-    /* read ini, type CONFIGURE_TYPE_MAIN */
-    err =
-        _mmcamcorder_conf_get_info (hcam, 0, MMFW_CONFIG_MAIN_FILE, &cam_conf);
-    if (err != MM_ERROR_NONE || !cam_conf) {
-      ml_loge ("Failed to load conf %s.", MMFW_CONFIG_MAIN_FILE);
-      goto mm_error;
-    }
-
-    if (video_src) {
-      /* category CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT */
-      status =
-          ml_tizen_mm_replace_element (hcam, cam_conf, 1, "VideosrcElement",
-          ML_TIZEN_CAM_VIDEO_SRC, result);
-      if (status != ML_ERROR_NONE)
-        goto mm_error;
-    }
-
-    if (audio_src) {
-      /* category CONFIGURE_CATEGORY_MAIN_AUDIO_INPUT */
-      status =
-          ml_tizen_mm_replace_element (hcam, cam_conf, 2, "AudiosrcElement",
-          ML_TIZEN_CAM_AUDIO_SRC, result);
-      if (status != ML_ERROR_NONE)
-        goto mm_error;
-    }
-
-    /* initialize rm handle */
-    status =
-        ml_tizen_mm_res_initialize (pipe, (video_src != NULL),
-        (audio_src != NULL));
-    if (status != ML_ERROR_NONE)
-      goto mm_error;
-
-    /* get the camera resource using mm resource manager */
-    status =
-        ml_tizen_mm_res_acquire (pipe, MM_RESOURCE_MANAGER_RES_TYPE_CAMERA);
-    if (status != ML_ERROR_NONE)
-      goto mm_error;
-  }
-
-  /* done */
-  status = ML_ERROR_NONE;
-
-mm_error:
-  if (cam_conf)
-    _mmcamcorder_conf_release_info (hcam, &cam_conf);
-
-  if (hcam)
-    mm_camcorder_destroy (hcam);
-
-  return status;
-}
-#else
-/**
- * @brief A dummy function for Tizen 4.0
- */
-static void
-ml_tizen_mm_res_release (gpointer handle, gboolean destroy)
-{
-}
-
-/**
- * @brief A dummy function for Tizen 4.0
- */
-static int
-ml_tizen_mm_res_acquire (ml_pipeline_h pipe,
-    mm_resource_manager_res_type_e res_type)
-{
-  return ML_ERROR_NOT_SUPPORTED;
-}
-
-/**
- * @brief A dummy function for Tizen 4.0
- */
-static int
-ml_tizen_mm_convert_element (ml_pipeline_h pipe, gchar ** result,
-    gboolean is_internal)
-{
-  return ML_ERROR_NOT_SUPPORTED;
-}
-#endif
-
-/**
- * @brief Releases the resource handle of Tizen.
- */
-void
-ml_tizen_release_resource (gpointer handle, const gchar * res_type)
-{
-  if (g_str_equal (res_type, TIZEN_RES_MM)) {
-    ml_tizen_mm_res_release (handle, TRUE);
-  }
-}
-
-/**
- * @brief Gets the resource handle of Tizen.
- */
-int
-ml_tizen_get_resource (ml_pipeline_h pipe, const gchar * res_type)
-{
-  int status = ML_ERROR_NONE;
-
-  if (g_str_equal (res_type, TIZEN_RES_MM)) {
-    /* iterate all handle and acquire res if released */
-    status = ml_tizen_mm_res_acquire (pipe, MM_RESOURCE_MANAGER_RES_TYPE_MAX);
-  }
-
-  return status;
-}
-
-/**
- * @brief Converts predefined element for Tizen.
- */
-int
-ml_tizen_convert_element (ml_pipeline_h pipe, gchar ** result,
-    gboolean is_internal)
-{
-  int status;
-
-  /* convert predefined element of mulitmedia fw */
-  status = ml_tizen_mm_convert_element (pipe, result, is_internal);
-
-  return status;
-}
diff --git a/api/capi/src/nnstreamer-capi-util.c b/api/capi/src/nnstreamer-capi-util.c
deleted file mode 100644 (file)
index 1dfeec0..0000000
+++ /dev/null
@@ -1,1329 +0,0 @@
-/**
- * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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-capi-util.c
- * @date 10 June 2019
- * @brief NNStreamer/Utilities C-API Wrapper.
- * @see        https://github.com/nnstreamer/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#include <string.h>
-
-#include "nnstreamer.h"
-#include "nnstreamer-capi-private.h"
-#include "nnstreamer_plugin_api.h"
-#include "nnstreamer_plugin_api_filter.h"
-#include "nnstreamer_internal.h"
-
-/**
- * @brief The name of sub-plugin for defined neural net frameworks.
- * @note The sub-plugin for Android is not declared (e.g., snap)
- */
-static const char *ml_nnfw_subplugin_name[] = {
-  [ML_NNFW_TYPE_ANY] = "any",   /* DO NOT use this name ('any') to get the sub-plugin */
-  [ML_NNFW_TYPE_CUSTOM_FILTER] = "custom",
-  [ML_NNFW_TYPE_TENSORFLOW_LITE] = "tensorflow-lite",
-  [ML_NNFW_TYPE_TENSORFLOW] = "tensorflow",
-  [ML_NNFW_TYPE_NNFW] = "nnfw",
-  [ML_NNFW_TYPE_MVNC] = "movidius-ncsdk2",
-  [ML_NNFW_TYPE_OPENVINO] = "openvino",
-  [ML_NNFW_TYPE_VIVANTE] = "vivante",
-  [ML_NNFW_TYPE_EDGE_TPU] = "edgetpu",
-  [ML_NNFW_TYPE_ARMNN] = "armnn",
-  [ML_NNFW_TYPE_SNPE] = "snpe",
-  [ML_NNFW_TYPE_PYTORCH] = "pytorch",
-  NULL
-};
-
-/**
- * @brief Allocates a tensors information handle with default value.
- */
-int
-ml_tensors_info_create (ml_tensors_info_h * info)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  *info = tensors_info = g_new0 (ml_tensors_info_s, 1);
-  if (tensors_info == NULL) {
-    ml_loge ("Failed to allocate the tensors info handle.");
-    return ML_ERROR_OUT_OF_MEMORY;
-  }
-
-  /* init tensors info struct */
-  return ml_tensors_info_initialize (tensors_info);
-}
-
-/**
- * @brief Allocates a tensors information handle from gst info.
- */
-int
-ml_tensors_info_create_from_gst (ml_tensors_info_h * ml_info,
-    GstTensorsInfo * gst_info)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!ml_info || !gst_info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  *ml_info = tensors_info = g_new0 (ml_tensors_info_s, 1);
-  if (tensors_info == NULL) {
-    ml_loge ("Failed to allocate the tensors info handle.");
-    return ML_ERROR_OUT_OF_MEMORY;
-  }
-
-  /* init and copy tensors info from gst struct */
-  ml_tensors_info_initialize (tensors_info);
-  ml_tensors_info_copy_from_gst (tensors_info, gst_info);
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Frees the given handle of a tensors information.
- */
-int
-ml_tensors_info_destroy (ml_tensors_info_h info)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  if (!tensors_info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  ml_tensors_info_free (tensors_info);
-  g_free (tensors_info);
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Initializes the tensors information with default value.
- */
-int
-ml_tensors_info_initialize (ml_tensors_info_s * info)
-{
-  guint i, j;
-
-  if (!info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  info->num_tensors = 0;
-
-  for (i = 0; i < ML_TENSOR_SIZE_LIMIT; i++) {
-    info->info[i].name = NULL;
-    info->info[i].type = ML_TENSOR_TYPE_UNKNOWN;
-
-    for (j = 0; j < ML_TENSOR_RANK_LIMIT; j++) {
-      info->info[i].dimension[j] = 0;
-    }
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Validates the given tensor info is valid.
- */
-static gboolean
-ml_tensor_info_validate (const ml_tensor_info_s * info)
-{
-  guint i;
-
-  if (!info)
-    return FALSE;
-
-  if (info->type < 0 || info->type >= ML_TENSOR_TYPE_UNKNOWN)
-    return FALSE;
-
-  for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
-    if (info->dimension[i] == 0)
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-/**
- * @brief Compares the given tensor info.
- */
-static gboolean
-ml_tensor_info_compare (const ml_tensor_info_s * i1,
-    const ml_tensor_info_s * i2)
-{
-  guint i;
-
-  if (i1 == NULL || i2 == NULL)
-    return FALSE;
-
-  if (i1->type != i2->type)
-    return FALSE;
-
-  for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
-    if (i1->dimension[i] != i2->dimension[i])
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-/**
- * @brief Validates the given tensors info is valid.
- */
-int
-ml_tensors_info_validate (const ml_tensors_info_h info, bool * valid)
-{
-  ml_tensors_info_s *tensors_info;
-  guint i;
-
-  check_feature_state ();
-
-  if (!valid)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  if (!tensors_info || tensors_info->num_tensors < 1)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init false */
-  *valid = false;
-
-  for (i = 0; i < tensors_info->num_tensors; i++) {
-    if (!ml_tensor_info_validate (&tensors_info->info[i]))
-      goto done;
-  }
-
-  *valid = true;
-
-done:
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Compares the given tensors information.
- */
-int
-ml_tensors_info_compare (const ml_tensors_info_h info1,
-    const ml_tensors_info_h info2, bool * equal)
-{
-  ml_tensors_info_s *i1, *i2;
-  guint i;
-
-  check_feature_state ();
-
-  if (info1 == NULL || info2 == NULL || equal == NULL)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  i1 = (ml_tensors_info_s *) info1;
-  i2 = (ml_tensors_info_s *) info2;
-
-  /* init false */
-  *equal = false;
-
-  if (i1->num_tensors != i2->num_tensors)
-    goto done;
-
-  for (i = 0; i < i1->num_tensors; i++) {
-    if (!ml_tensor_info_compare (&i1->info[i], &i2->info[i]))
-      goto done;
-  }
-
-  *equal = true;
-
-done:
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Sets the number of tensors with given handle of tensors information.
- */
-int
-ml_tensors_info_set_count (ml_tensors_info_h info, unsigned int count)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!info || count > ML_TENSOR_SIZE_LIMIT)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-  tensors_info->num_tensors = count;
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Gets the number of tensors with given handle of tensors information.
- */
-int
-ml_tensors_info_get_count (ml_tensors_info_h info, unsigned int *count)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!info || !count)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-  *count = tensors_info->num_tensors;
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Sets the tensor name with given handle of tensors information.
- */
-int
-ml_tensors_info_set_tensor_name (ml_tensors_info_h info,
-    unsigned int index, const char *name)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  if (tensors_info->num_tensors <= index)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  if (tensors_info->info[index].name) {
-    g_free (tensors_info->info[index].name);
-    tensors_info->info[index].name = NULL;
-  }
-
-  if (name)
-    tensors_info->info[index].name = g_strdup (name);
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Gets the tensor name with given handle of tensors information.
- */
-int
-ml_tensors_info_get_tensor_name (ml_tensors_info_h info,
-    unsigned int index, char **name)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!info || !name)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  if (tensors_info->num_tensors <= index)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  *name = g_strdup (tensors_info->info[index].name);
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Sets the tensor type with given handle of tensors information.
- */
-int
-ml_tensors_info_set_tensor_type (ml_tensors_info_h info,
-    unsigned int index, const ml_tensor_type_e type)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  if (type == ML_TENSOR_TYPE_UNKNOWN)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  if (tensors_info->num_tensors <= index)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info->info[index].type = type;
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Gets the tensor type with given handle of tensors information.
- */
-int
-ml_tensors_info_get_tensor_type (ml_tensors_info_h info,
-    unsigned int index, ml_tensor_type_e * type)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!info || !type)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  if (tensors_info->num_tensors <= index)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  *type = tensors_info->info[index].type;
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Sets the tensor dimension with given handle of tensors information.
- */
-int
-ml_tensors_info_set_tensor_dimension (ml_tensors_info_h info,
-    unsigned int index, const ml_tensor_dimension dimension)
-{
-  ml_tensors_info_s *tensors_info;
-  guint i;
-
-  check_feature_state ();
-
-  if (!info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  if (tensors_info->num_tensors <= index)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
-    tensors_info->info[index].dimension[i] = dimension[i];
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Gets the tensor dimension with given handle of tensors information.
- */
-int
-ml_tensors_info_get_tensor_dimension (ml_tensors_info_h info,
-    unsigned int index, ml_tensor_dimension dimension)
-{
-  ml_tensors_info_s *tensors_info;
-  guint i;
-
-  check_feature_state ();
-
-  if (!info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  if (tensors_info->num_tensors <= index)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
-    dimension[i] = tensors_info->info[index].dimension[i];
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Gets the byte size of the given tensor info.
- */
-size_t
-ml_tensor_info_get_size (const ml_tensor_info_s * info)
-{
-  size_t tensor_size;
-  gint i;
-
-  if (!info)
-    return 0;
-
-  switch (info->type) {
-    case ML_TENSOR_TYPE_INT8:
-    case ML_TENSOR_TYPE_UINT8:
-      tensor_size = 1;
-      break;
-    case ML_TENSOR_TYPE_INT16:
-    case ML_TENSOR_TYPE_UINT16:
-      tensor_size = 2;
-      break;
-    case ML_TENSOR_TYPE_INT32:
-    case ML_TENSOR_TYPE_UINT32:
-    case ML_TENSOR_TYPE_FLOAT32:
-      tensor_size = 4;
-      break;
-    case ML_TENSOR_TYPE_FLOAT64:
-    case ML_TENSOR_TYPE_INT64:
-    case ML_TENSOR_TYPE_UINT64:
-      tensor_size = 8;
-      break;
-    default:
-      ml_loge ("In the given param, tensor type is invalid.");
-      return 0;
-  }
-
-  for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++) {
-    tensor_size *= info->dimension[i];
-  }
-
-  return tensor_size;
-}
-
-/**
- * @brief Gets the byte size of the given handle of tensors information.
- */
-int
-ml_tensors_info_get_tensor_size (ml_tensors_info_h info,
-    int index, size_t * data_size)
-{
-  ml_tensors_info_s *tensors_info;
-
-  check_feature_state ();
-
-  if (!info || !data_size)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  tensors_info = (ml_tensors_info_s *) info;
-
-  /* init 0 */
-  *data_size = 0;
-
-  if (index < 0) {
-    guint i;
-
-    /* get total byte size */
-    for (i = 0; i < tensors_info->num_tensors; i++) {
-      *data_size += ml_tensor_info_get_size (&tensors_info->info[i]);
-    }
-  } else {
-    if (tensors_info->num_tensors <= index)
-      return ML_ERROR_INVALID_PARAMETER;
-
-    *data_size = ml_tensor_info_get_size (&tensors_info->info[index]);
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Frees the tensors info pointer.
- */
-void
-ml_tensors_info_free (ml_tensors_info_s * info)
-{
-  gint i;
-
-  if (!info)
-    return;
-
-  for (i = 0; i < ML_TENSOR_SIZE_LIMIT; i++) {
-    if (info->info[i].name) {
-      g_free (info->info[i].name);
-      info->info[i].name = NULL;
-    }
-  }
-
-  ml_tensors_info_initialize (info);
-}
-
-/**
- * @brief Frees the tensors data pointer.
- */
-int
-ml_tensors_data_destroy (ml_tensors_data_h data)
-{
-  gint status = ML_ERROR_NONE;
-  ml_tensors_data_s *_data;
-  guint i;
-
-  check_feature_state ();
-
-  if (!data)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  _data = (ml_tensors_data_s *) data;
-
-  if (_data->handle != NULL) {
-    status = ml_single_destroy_notify (_data->handle, _data);
-  } else {
-    for (i = 0; i < ML_TENSOR_SIZE_LIMIT; i++) {
-      if (_data->tensors[i].tensor) {
-        g_free (_data->tensors[i].tensor);
-        _data->tensors[i].tensor = NULL;
-      }
-    }
-  }
-
-  g_free (_data);
-  return status;
-}
-
-/**
- * @brief Allocates a tensor data frame with the given tensors info. (more info in nnstreamer.h)
- * @note Memory for data buffer is not allocated.
- */
-int
-ml_tensors_data_create_no_alloc (const ml_tensors_info_h info,
-    ml_tensors_data_h * data)
-{
-  ml_tensors_data_s *_data;
-  ml_tensors_info_s *_info;
-  gint i;
-
-  check_feature_state ();
-
-  if (data == NULL)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init null */
-  *data = NULL;
-
-  _data = g_new0 (ml_tensors_data_s, 1);
-  if (!_data) {
-    ml_loge ("Failed to allocate the tensors data handle.");
-    return ML_ERROR_OUT_OF_MEMORY;
-  }
-
-  _data->handle = NULL;
-  _info = (ml_tensors_info_s *) info;
-  if (_info != NULL) {
-    _data->num_tensors = _info->num_tensors;
-    for (i = 0; i < _data->num_tensors; i++) {
-      _data->tensors[i].size = ml_tensor_info_get_size (&_info->info[i]);
-      _data->tensors[i].tensor = NULL;
-    }
-  }
-
-  *data = _data;
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Clones the given tensor data frame from the given tensors data. (more info in nnstreamer.h)
- * @note Memory ptr for data buffer is copied. No new memory for data buffer is allocated.
- */
-int
-ml_tensors_data_clone_no_alloc (const ml_tensors_data_s * data_src,
-    ml_tensors_data_h * data)
-{
-  ml_tensors_data_s *_data;
-
-  check_feature_state ();
-
-  if (data == NULL || data_src == NULL)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init null */
-  *data = NULL;
-
-  _data = g_try_new0 (ml_tensors_data_s, 1);
-  if (!_data) {
-    ml_loge ("Failed to allocate the tensors data handle.");
-    return ML_ERROR_OUT_OF_MEMORY;
-  }
-
-  _data->handle = NULL;
-  _data->num_tensors = data_src->num_tensors;
-  memcpy (_data->tensors, data_src->tensors,
-      sizeof (ml_tensor_data_s) * data_src->num_tensors);
-
-  *data = _data;
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Allocates a tensor data frame with the given tensors info. (more info in nnstreamer.h)
- */
-int
-ml_tensors_data_create (const ml_tensors_info_h info, ml_tensors_data_h * data)
-{
-  gint status = ML_ERROR_STREAMS_PIPE;
-  ml_tensors_data_s *_data = NULL;
-  gint i;
-
-  check_feature_state ();
-
-  if (info == NULL || data == NULL)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  if (!ml_tensors_info_is_valid (info)) {
-    nns_loge ("Given tensors information is invalid.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  status =
-      ml_tensors_data_create_no_alloc (info, (ml_tensors_data_h *) & _data);
-
-  if (status != ML_ERROR_NONE) {
-    return status;
-  }
-
-  for (i = 0; i < _data->num_tensors; i++) {
-    _data->tensors[i].tensor = g_malloc0 (_data->tensors[i].size);
-    if (_data->tensors[i].tensor == NULL) {
-      status = ML_ERROR_OUT_OF_MEMORY;
-      goto failed;
-    }
-  }
-
-  *data = _data;
-  return ML_ERROR_NONE;
-
-failed:
-  for (i = 0; i < _data->num_tensors; i++) {
-    g_free (_data->tensors[i].tensor);
-  }
-  g_free (_data);
-
-  ml_loge ("Failed to allocate the memory block.");
-  return status;
-}
-
-/**
- * @brief Gets a tensor data of given handle.
- */
-int
-ml_tensors_data_get_tensor_data (ml_tensors_data_h data, unsigned int index,
-    void **raw_data, size_t * data_size)
-{
-  ml_tensors_data_s *_data;
-
-  check_feature_state ();
-
-  if (!data || !raw_data || !data_size)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  _data = (ml_tensors_data_s *) data;
-
-  if (_data->num_tensors <= index)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  *raw_data = _data->tensors[index].tensor;
-  *data_size = _data->tensors[index].size;
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Copies a tensor data to given handle.
- */
-int
-ml_tensors_data_set_tensor_data (ml_tensors_data_h data, unsigned int index,
-    const void *raw_data, const size_t data_size)
-{
-  ml_tensors_data_s *_data;
-
-  check_feature_state ();
-
-  if (!data || !raw_data)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  _data = (ml_tensors_data_s *) data;
-
-  if (_data->num_tensors <= index)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  if (data_size <= 0 || _data->tensors[index].size < data_size)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  if (_data->tensors[index].tensor != raw_data)
-    memcpy (_data->tensors[index].tensor, raw_data, data_size);
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Copies tensor meta info.
- */
-int
-ml_tensors_info_clone (ml_tensors_info_h dest, const ml_tensors_info_h src)
-{
-  ml_tensors_info_s *dest_info, *src_info;
-  guint i, j;
-
-  check_feature_state ();
-
-  dest_info = (ml_tensors_info_s *) dest;
-  src_info = (ml_tensors_info_s *) src;
-
-  if (!dest_info || !src_info)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  ml_tensors_info_initialize (dest_info);
-
-  dest_info->num_tensors = src_info->num_tensors;
-
-  for (i = 0; i < dest_info->num_tensors; i++) {
-    dest_info->info[i].name =
-        (src_info->info[i].name) ? g_strdup (src_info->info[i].name) : NULL;
-    dest_info->info[i].type = src_info->info[i].type;
-
-    for (j = 0; j < ML_TENSOR_RANK_LIMIT; j++)
-      dest_info->info[i].dimension[j] = src_info->info[i].dimension[j];
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Copies tensor meta info from gst tensors info.
- */
-void
-ml_tensors_info_copy_from_gst (ml_tensors_info_s * ml_info,
-    const GstTensorsInfo * gst_info)
-{
-  guint i, j;
-  guint max_dim;
-
-  if (!ml_info || !gst_info)
-    return;
-
-  ml_tensors_info_initialize (ml_info);
-  max_dim = MIN (ML_TENSOR_RANK_LIMIT, NNS_TENSOR_RANK_LIMIT);
-
-  ml_info->num_tensors = gst_info->num_tensors;
-
-  for (i = 0; i < gst_info->num_tensors; i++) {
-    /* Copy name string */
-    if (gst_info->info[i].name) {
-      ml_info->info[i].name = g_strdup (gst_info->info[i].name);
-    }
-
-    /* Set tensor type */
-    switch (gst_info->info[i].type) {
-      case _NNS_INT32:
-        ml_info->info[i].type = ML_TENSOR_TYPE_INT32;
-        break;
-      case _NNS_UINT32:
-        ml_info->info[i].type = ML_TENSOR_TYPE_UINT32;
-        break;
-      case _NNS_INT16:
-        ml_info->info[i].type = ML_TENSOR_TYPE_INT16;
-        break;
-      case _NNS_UINT16:
-        ml_info->info[i].type = ML_TENSOR_TYPE_UINT16;
-        break;
-      case _NNS_INT8:
-        ml_info->info[i].type = ML_TENSOR_TYPE_INT8;
-        break;
-      case _NNS_UINT8:
-        ml_info->info[i].type = ML_TENSOR_TYPE_UINT8;
-        break;
-      case _NNS_FLOAT64:
-        ml_info->info[i].type = ML_TENSOR_TYPE_FLOAT64;
-        break;
-      case _NNS_FLOAT32:
-        ml_info->info[i].type = ML_TENSOR_TYPE_FLOAT32;
-        break;
-      case _NNS_INT64:
-        ml_info->info[i].type = ML_TENSOR_TYPE_INT64;
-        break;
-      case _NNS_UINT64:
-        ml_info->info[i].type = ML_TENSOR_TYPE_UINT64;
-        break;
-      default:
-        ml_info->info[i].type = ML_TENSOR_TYPE_UNKNOWN;
-        break;
-    }
-
-    /* Set dimension */
-    for (j = 0; j < max_dim; j++) {
-      ml_info->info[i].dimension[j] = gst_info->info[i].dimension[j];
-    }
-
-    for (; j < ML_TENSOR_RANK_LIMIT; j++) {
-      ml_info->info[i].dimension[j] = 1;
-    }
-  }
-}
-
-/**
- * @brief Copies tensor meta info from gst tensors info.
- */
-void
-ml_tensors_info_copy_from_ml (GstTensorsInfo * gst_info,
-    const ml_tensors_info_s * ml_info)
-{
-  guint i, j;
-  guint max_dim;
-
-  if (!gst_info || !ml_info)
-    return;
-
-  gst_tensors_info_init (gst_info);
-  max_dim = MIN (ML_TENSOR_RANK_LIMIT, NNS_TENSOR_RANK_LIMIT);
-
-  gst_info->num_tensors = ml_info->num_tensors;
-
-  for (i = 0; i < ml_info->num_tensors; i++) {
-    /* Copy name string */
-    if (ml_info->info[i].name) {
-      gst_info->info[i].name = g_strdup (ml_info->info[i].name);
-    }
-
-    /* Set tensor type */
-    switch (ml_info->info[i].type) {
-      case ML_TENSOR_TYPE_INT32:
-        gst_info->info[i].type = _NNS_INT32;
-        break;
-      case ML_TENSOR_TYPE_UINT32:
-        gst_info->info[i].type = _NNS_UINT32;
-        break;
-      case ML_TENSOR_TYPE_INT16:
-        gst_info->info[i].type = _NNS_INT16;
-        break;
-      case ML_TENSOR_TYPE_UINT16:
-        gst_info->info[i].type = _NNS_UINT16;
-        break;
-      case ML_TENSOR_TYPE_INT8:
-        gst_info->info[i].type = _NNS_INT8;
-        break;
-      case ML_TENSOR_TYPE_UINT8:
-        gst_info->info[i].type = _NNS_UINT8;
-        break;
-      case ML_TENSOR_TYPE_FLOAT64:
-        gst_info->info[i].type = _NNS_FLOAT64;
-        break;
-      case ML_TENSOR_TYPE_FLOAT32:
-        gst_info->info[i].type = _NNS_FLOAT32;
-        break;
-      case ML_TENSOR_TYPE_INT64:
-        gst_info->info[i].type = _NNS_INT64;
-        break;
-      case ML_TENSOR_TYPE_UINT64:
-        gst_info->info[i].type = _NNS_UINT64;
-        break;
-      default:
-        gst_info->info[i].type = _NNS_END;
-        break;
-    }
-
-    /* Set dimension */
-    for (j = 0; j < max_dim; j++) {
-      gst_info->info[i].dimension[j] = ml_info->info[i].dimension[j];
-    }
-
-    for (; j < NNS_TENSOR_RANK_LIMIT; j++) {
-      gst_info->info[i].dimension[j] = 1;
-    }
-  }
-}
-
-/**
- * @brief Initializes the GStreamer library. This is internal function.
- */
-int
-ml_initialize_gstreamer (void)
-{
-  GError *err = NULL;
-
-  if (!gst_init_check (NULL, NULL, &err)) {
-    if (err) {
-      ml_loge ("GStreamer has the following error: %s", err->message);
-      g_clear_error (&err);
-    } else {
-      ml_loge ("Cannot initialize GStreamer. Unknown reason.");
-    }
-
-    return ML_ERROR_STREAMS_PIPE;
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Internal helper function to validate model files.
- */
-static int
-_ml_validate_model_file (const char *const *model,
-    const unsigned int num_models, gboolean * is_dir)
-{
-  guint i;
-
-  if (!model || num_models < 1) {
-    ml_loge ("The required param, model is not provided (null).");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (g_file_test (model[0], G_FILE_TEST_IS_DIR)) {
-    *is_dir = TRUE;
-    return ML_ERROR_NONE;
-  }
-
-  for (i = 0; i < num_models; i++) {
-    if (!model[i] || !g_file_test (model[i], G_FILE_TEST_IS_REGULAR)) {
-      ml_loge ("The given param, model path [%s] is invalid or not given.",
-          GST_STR_NULL (model[i]));
-      return ML_ERROR_INVALID_PARAMETER;
-    }
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Validates the nnfw model file.
- * @since_tizen 5.5
- * @param[in] model The path of model file.
- * @param[in/out] nnfw The type of NNFW.
- * @return @c 0 on success. Otherwise a negative error value.
- * @retval #ML_ERROR_NONE Successful
- * @retval #ML_ERROR_NOT_SUPPORTED Not supported, or framework to support this model file is unavailable in the environment.
- * @retval #ML_ERROR_INVALID_PARAMETER Given parameter is invalid.
- */
-int
-ml_validate_model_file (const char *const *model,
-    const unsigned int num_models, ml_nnfw_type_e * nnfw)
-{
-  int status = ML_ERROR_NONE;
-  ml_nnfw_type_e detected = ML_NNFW_TYPE_ANY;
-  gboolean is_dir = FALSE;
-  gchar *pos, *fw_name;
-  gchar **file_ext = NULL;
-  guint i;
-
-  if (!nnfw)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  status = _ml_validate_model_file (model, num_models, &is_dir);
-  if (status != ML_ERROR_NONE)
-    return status;
-
-  /**
-   * @note detect-fw checks the file ext and returns proper fw name for given models.
-   * If detected fw and given nnfw are same, we don't need to check the file extension.
-   * If any condition for auto detection is added later, below code also should be updated.
-   */
-  fw_name = gst_tensor_filter_detect_framework (model, num_models, FALSE);
-  detected = ml_get_nnfw_type_by_subplugin_name (fw_name);
-  g_free (fw_name);
-
-  if (*nnfw == ML_NNFW_TYPE_ANY) {
-    if (detected == ML_NNFW_TYPE_ANY) {
-      ml_loge ("The given model has unknown or not supported extension.");
-      status = ML_ERROR_INVALID_PARAMETER;
-    } else {
-      ml_logi ("The given model is supposed a %s model.",
-          ml_get_nnfw_subplugin_name (detected));
-      *nnfw = detected;
-    }
-
-    goto done;
-  } else if (is_dir && *nnfw != ML_NNFW_TYPE_NNFW) {
-    /* supposed it is ONE if given model is directory */
-    ml_loge ("The given model is directory, check model and framework.");
-    status = ML_ERROR_INVALID_PARAMETER;
-    goto done;
-  } else if (detected == *nnfw) {
-    /* Expected framework, nothing to do. */
-    goto done;
-  }
-
-  /* Handle mismatched case, check file extension. */
-  file_ext = g_malloc0 (sizeof (char *) * (num_models + 1));
-  for (i = 0; i < num_models; i++) {
-    if ((pos = strrchr (model[i], '.')) == NULL) {
-      ml_loge ("The given model [%s] has invalid extension.", model[i]);
-      status = ML_ERROR_INVALID_PARAMETER;
-      goto done;
-    }
-
-    file_ext[i] = g_ascii_strdown (pos, -1);
-  }
-
-  /** @todo Make sure num_models is correct for each nnfw type */
-  switch (*nnfw) {
-    case ML_NNFW_TYPE_NNFW:
-      /**
-       * We cannot check the file ext with NNFW.
-       * NNFW itself will validate metadata and model file.
-       */
-      break;
-    case ML_NNFW_TYPE_MVNC:
-    case ML_NNFW_TYPE_OPENVINO:
-    case ML_NNFW_TYPE_EDGE_TPU:
-      /** @todo Need to check method to validate model */
-      ml_loge ("Given NNFW is not supported yet.");
-      status = ML_ERROR_NOT_SUPPORTED;
-      break;
-    case ML_NNFW_TYPE_SNAP:
-#if !defined (__ANDROID__)
-      ml_loge ("SNAP only can be included in Android (arm64-v8a only).");
-      status = ML_ERROR_NOT_SUPPORTED;
-#endif
-      /* SNAP requires multiple files, set supported if model file exists. */
-      break;
-    case ML_NNFW_TYPE_ARMNN:
-      if (!g_str_equal (file_ext[0], ".caffemodel") &&
-          !g_str_equal (file_ext[0], ".tflite") &&
-          !g_str_equal (file_ext[0], ".pb") &&
-          !g_str_equal (file_ext[0], ".prototxt")) {
-        status = ML_ERROR_INVALID_PARAMETER;
-      }
-      break;
-    default:
-      status = ML_ERROR_INVALID_PARAMETER;
-      break;
-  }
-
-done:
-  if (status == ML_ERROR_NONE) {
-    if (!ml_nnfw_is_available (*nnfw, ML_NNFW_HW_ANY)) {
-      ml_loge ("%s is not available.", ml_get_nnfw_subplugin_name (*nnfw));
-      status = ML_ERROR_NOT_SUPPORTED;
-    }
-  } else {
-    ml_loge ("The given model file is invalid.");
-  }
-
-  g_strfreev (file_ext);
-  return status;
-}
-
-/**
- * @brief Convert c-api based hw to internal representation
- */
-static accl_hw
-ml_nnfw_to_accl_hw (const ml_nnfw_hw_e hw)
-{
-  switch (hw) {
-    case ML_NNFW_HW_ANY:
-      return ACCL_DEFAULT;
-    case ML_NNFW_HW_AUTO:
-      return ACCL_AUTO;
-    case ML_NNFW_HW_CPU:
-      return ACCL_CPU;
-#if defined (__aarch64__) || defined (__arm__)
-    case ML_NNFW_HW_CPU_NEON:
-      return ACCL_CPU_NEON;
-#else
-    case ML_NNFW_HW_CPU_SIMD:
-      return ACCL_CPU_SIMD;
-#endif
-    case ML_NNFW_HW_GPU:
-      return ACCL_GPU;
-    case ML_NNFW_HW_NPU:
-      return ACCL_NPU;
-    case ML_NNFW_HW_NPU_MOVIDIUS:
-      return ACCL_NPU_MOVIDIUS;
-    case ML_NNFW_HW_NPU_EDGE_TPU:
-      return ACCL_NPU_EDGE_TPU;
-    case ML_NNFW_HW_NPU_VIVANTE:
-      return ACCL_NPU_VIVANTE;
-    case ML_NNFW_HW_NPU_SR:
-      /** @todo how to get srcn npu */
-      return ACCL_NPU_SR;
-    default:
-      return ACCL_AUTO;
-  }
-}
-
-/**
- * @brief Internal function to convert accelerator as tensor_filter property format.
- * @note returned value must be freed by the caller
- * @note More details on format can be found in gst_tensor_filter_install_properties() in tensor_filter_common.c.
- */
-char *
-ml_nnfw_to_str_prop (const ml_nnfw_hw_e hw)
-{
-  const gchar *hw_name;
-  const gchar *use_accl = "true:";
-  gchar *str_prop = NULL;
-
-  hw_name = get_accl_hw_str (ml_nnfw_to_accl_hw (hw));
-  str_prop = g_strdup_printf ("%s%s", use_accl, hw_name);
-
-  return str_prop;
-}
-
-/**
- * @brief Internal function to get the sub-plugin name.
- */
-const char *
-ml_get_nnfw_subplugin_name (ml_nnfw_type_e nnfw)
-{
-  /* check sub-plugin for android */
-  if (nnfw == ML_NNFW_TYPE_SNAP)
-    return "snap";
-
-  return ml_nnfw_subplugin_name[nnfw];
-}
-
-/**
- * @brief Internal function to get the nnfw type.
- */
-ml_nnfw_type_e
-ml_get_nnfw_type_by_subplugin_name (const char *name)
-{
-  ml_nnfw_type_e nnfw_type = ML_NNFW_TYPE_ANY;
-  int idx = -1;
-
-  g_return_val_if_fail (name != NULL, ML_NNFW_TYPE_ANY);
-
-  idx = find_key_strv (ml_nnfw_subplugin_name, name);
-  if (idx < 0) {
-    /* check sub-plugin for android */
-    if (g_ascii_strcasecmp (name, "snap") == 0)
-      nnfw_type = ML_NNFW_TYPE_SNAP;
-    else
-      ml_logw ("Cannot find nnfw, %s is invalid name.", GST_STR_NULL (name));
-  } else {
-    nnfw_type = (ml_nnfw_type_e) idx;
-  }
-
-  return nnfw_type;
-}
-
-/**
- * @brief Checks the availability of the given execution environments.
- */
-int
-ml_check_nnfw_availability (ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw,
-    bool * available)
-{
-  const char *fw_name = NULL;
-
-  check_feature_state ();
-
-  if (!available)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  /* init false */
-  *available = false;
-
-  if (nnfw == ML_NNFW_TYPE_ANY)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  fw_name = ml_get_nnfw_subplugin_name (nnfw);
-
-  if (fw_name) {
-    if (nnstreamer_filter_find (fw_name) != NULL) {
-      accl_hw accl = ml_nnfw_to_accl_hw (hw);
-
-      if (gst_tensor_filter_check_hw_availability (fw_name, accl)) {
-        *available = true;
-      } else {
-        ml_logw ("%s is supported but not with the specified hardware.",
-            fw_name);
-      }
-    } else {
-      ml_logw ("%s is not supported.", fw_name);
-    }
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Checks the element is registered and available on the pipeline.
- */
-int
-ml_check_element_availability (const char *element_name, bool * available)
-{
-  GstElementFactory *factory;
-  int status;
-
-  check_feature_state ();
-
-  if (!element_name || !available)
-    return ML_ERROR_INVALID_PARAMETER;
-
-  status = ml_initialize_gstreamer ();
-  if (status != ML_ERROR_NONE)
-    return status;
-
-  /* init false */
-  *available = false;
-
-  factory = gst_element_factory_find (element_name);
-  if (factory) {
-    GstPluginFeature *feature = GST_PLUGIN_FEATURE (factory);
-    const gchar *plugin_name = gst_plugin_feature_get_plugin_name (feature);
-
-    /* check restricted element */
-    status = ml_check_plugin_availability (plugin_name, element_name);
-    if (status == ML_ERROR_NONE)
-      *available = true;
-
-    gst_object_unref (factory);
-  }
-
-  return ML_ERROR_NONE;
-}
-
-/**
- * @brief Checks the availability of the plugin.
- */
-int
-ml_check_plugin_availability (const char *plugin_name, const char *element_name)
-{
-  static gboolean list_loaded = FALSE;
-  static gchar **restricted_elements = NULL;
-
-  if (!plugin_name || !element_name) {
-    ml_loge ("The name is invalid, failed to check the availability.");
-    return ML_ERROR_INVALID_PARAMETER;
-  }
-
-  if (!list_loaded) {
-    gboolean restricted;
-
-    restricted =
-        nnsconf_get_custom_value_bool ("element-restriction",
-        "enable_element_restriction", FALSE);
-    if (restricted) {
-      gchar *elements;
-
-      /* check white-list of available plugins */
-      elements =
-          nnsconf_get_custom_value_string ("element-restriction",
-          "restricted_elements");
-      if (elements) {
-        restricted_elements = g_strsplit_set (elements, " ,;", -1);
-        g_free (elements);
-      }
-    }
-
-    list_loaded = TRUE;
-  }
-
-  /* nnstreamer elements */
-  if (g_str_has_prefix (plugin_name, "nnstreamer") &&
-      g_str_has_prefix (element_name, "tensor_")) {
-    return ML_ERROR_NONE;
-  }
-
-  if (restricted_elements &&
-      find_key_strv ((const gchar **) restricted_elements, element_name) < 0) {
-    ml_logw ("The element %s is restricted.", element_name);
-    return ML_ERROR_NOT_SUPPORTED;
-  }
-
-  return ML_ERROR_NONE;
-}