1. get required method ids to improve performance when initializing the pipe info.
2. add internal method to handle arraylist.
Signed-off-by: Jaeyun <jy1210.jung@samsung.com>
}
/**
+ * 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
* Internal method called from native to add new info.
*/
private void appendInfo(String name, int type, int[] dimension) {
- addTensorInfo(name, convertType(type), dimension);
+ addTensorInfo(name, TensorInfo.convertType(type), dimension);
}
/**
- * Internal method to get the tensor type from int value.
+ * Internal method called from native to get the array of tensor info.
*/
- private 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;
+ private Object[] getInfoArray() {
+ return mInfoList.toArray();
}
/**
*/
private static class TensorInfo {
private String name = null;
- private NNStreamer.TensorType type = NNStreamer.TensorType.UNKNOWN;
+ 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) {
throw new IllegalArgumentException("Given tensor type is unknown or unsupported type");
}
- this.type = type;
+ this.type = type.ordinal();
}
public NNStreamer.TensorType getType() {
- return this.type;
- }
-
- public int getTypeValue() {
- return this.type.ordinal();
+ return convertType(this.type);
}
public void setDimension(@NonNull int[] dimension) {
}
public int getSize() {
- int size = 0;
-
- if (type == NNStreamer.TensorType.INT32 ||
- type == NNStreamer.TensorType.UINT32 ||
- type == NNStreamer.TensorType.FLOAT32) {
- size = 4;
- } else if (type == NNStreamer.TensorType.INT16 ||
- type == NNStreamer.TensorType.UINT16) {
- size = 2;
- } else if (type == NNStreamer.TensorType.INT8 ||
- type == NNStreamer.TensorType.UINT8) {
- size = 1;
- } else if (type == NNStreamer.TensorType.FLOAT64 ||
- type == NNStreamer.TensorType.INT64 ||
- type == NNStreamer.TensorType.UINT64) {
- size = 8;
+ 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++) {
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;
+ }
}
}
}
/**
+ * @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>", "()V");
+ info->mid_add_data = (*env)->GetMethodID (env, info->cls, "addTensorData",
+ "([B)V");
+ info->mid_get_array = (*env)->GetMethodID (env, info->cls, "getDataArray",
+ "()[Ljava/lang/Object;");
+ info->mid_set_info = (*env)->GetMethodID (env, info->cls, "setTensorsInfo",
+ "(L" NNS_CLS_TINFO ";)V");
+ 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_pipe_type_e type)
{
pipeline_info_s *pipe_info;
- jclass cls_data, cls_info;
+ jclass cls;
pipe_info = g_new0 (pipeline_info_s, 1);
g_return_val_if_fail (pipe_info != NULL, NULL);
pipe_info->version = (*env)->GetVersion (env);
pipe_info->instance = (*env)->NewGlobalRef (env, thiz);
- cls_data = (*env)->FindClass (env, "org/nnsuite/nnstreamer/TensorsData");
- pipe_info->cls_tensors_data = (*env)->NewGlobalRef (env, cls_data);
- (*env)->DeleteLocalRef (env, cls_data);
+ cls = (*env)->GetObjectClass (env, pipe_info->instance);
+ pipe_info->cls = (*env)->NewGlobalRef (env, cls);
+ (*env)->DeleteLocalRef (env, cls);
- cls_info = (*env)->FindClass (env, "org/nnsuite/nnstreamer/TensorsInfo");
- pipe_info->cls_tensors_info = (*env)->NewGlobalRef (env, cls_info);
- (*env)->DeleteLocalRef (env, cls_info);
+ 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;
}
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);
+ }
+
g_hash_table_destroy (pipe_info->element_handles);
pipe_info->element_handles = NULL;
g_mutex_unlock (&pipe_info->lock);
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);
- (*env)->DeleteGlobalRef (env, pipe_info->cls_tensors_data);
- (*env)->DeleteGlobalRef (env, pipe_info->cls_tensors_info);
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 handle of given name.
*/
gpointer
ml_tensors_data_h data_h, ml_tensors_info_h info_h, jobject * result)
{
guint i;
- jmethodID mid_init, mid_add_data, mid_set_info;
+ data_class_info_s *dcls_info;
jobject obj_data = NULL;
ml_tensors_data_s *data;
g_return_val_if_fail (data_h, FALSE);
g_return_val_if_fail (result, FALSE);
+ dcls_info = &pipe_info->data_cls_info;
data = (ml_tensors_data_s *) data_h;
- /* method to generate tensors data */
- mid_init =
- (*env)->GetMethodID (env, pipe_info->cls_tensors_data, "<init>", "()V");
- mid_add_data =
- (*env)->GetMethodID (env, pipe_info->cls_tensors_data, "addTensorData",
- "([B)V");
- mid_set_info =
- (*env)->GetMethodID (env, pipe_info->cls_tensors_data, "setTensorsInfo",
- "(Lorg/nnsuite/nnstreamer/TensorsInfo;)V");
-
- obj_data = (*env)->NewObject (env, pipe_info->cls_tensors_data, mid_init);
+ obj_data = (*env)->NewObject (env, dcls_info->cls, dcls_info->mid_init);
if (!obj_data) {
nns_loge ("Failed to allocate object for tensors data.");
goto done;
goto done;
}
- (*env)->CallVoidMethod (env, obj_data, mid_set_info, obj_info);
+ (*env)->CallVoidMethod (env, obj_data, dcls_info->mid_set_info, obj_info);
(*env)->DeleteLocalRef (env, obj_info);
}
(*env)->SetByteArrayRegion (env, buffer, 0, buffer_size,
(jbyte *) data->tensors[i].tensor);
- (*env)->CallVoidMethod (env, obj_data, mid_add_data, buffer);
+ (*env)->CallVoidMethod (env, obj_data, dcls_info->mid_add_data, buffer);
(*env)->DeleteLocalRef (env, buffer);
}
jobject obj_data, 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;
- ml_tensors_info_s *info;
+ jobjectArray data_arr;
gboolean failed = FALSE;
g_return_val_if_fail (pipe_info, FALSE);
return FALSE;
}
+ dcls_info = &pipe_info->data_cls_info;
data = (ml_tensors_data_s *) (*data_h);
- /* get field 'mDataList' */
- jfieldID fid_arraylist =
- (*env)->GetFieldID (env, pipe_info->cls_tensors_data, "mDataList",
- "Ljava/util/ArrayList;");
- jobject obj_arraylist = (*env)->GetObjectField (env, obj_data, fid_arraylist);
-
- /* method to get tensors data */
- jclass cls_arraylist = (*env)->GetObjectClass (env, obj_arraylist);
- jmethodID mid_size = (*env)->GetMethodID (env, cls_arraylist, "size", "()I");
- jmethodID mid_get =
- (*env)->GetMethodID (env, cls_arraylist, "get", "(I)Ljava/lang/Object;");
+ data_arr = (*env)->CallObjectMethod (env, obj_data, dcls_info->mid_get_array);
/* number of tensors data */
- data->num_tensors =
- (unsigned int) (*env)->CallIntMethod (env, obj_arraylist, mid_size);
+ data->num_tensors = (unsigned int) (*env)->GetArrayLength (env, data_arr);
/* set tensor data */
for (i = 0; i < data->num_tensors; i++) {
- jobject tensor_data =
- (*env)->CallObjectMethod (env, obj_arraylist, mid_get, i);
+ jobject tensor = (*env)->GetObjectArrayElement (env, data_arr, i);
- if (tensor_data) {
- size_t data_size =
- (size_t) (*env)->GetDirectBufferCapacity (env, tensor_data);
- gpointer data_ptr = (*env)->GetDirectBufferAddress (env, tensor_data);
+ if (tensor) {
+ gsize data_size = (gsize) (*env)->GetDirectBufferCapacity (env, tensor);
+ gpointer data_ptr = (*env)->GetDirectBufferAddress (env, tensor);
data->tensors[i].tensor = g_malloc (data_size);
if (data->tensors[i].tensor == NULL) {
- nns_loge ("Failed to allocate memory %zd, data index %d.", data_size,
- i);
- (*env)->DeleteLocalRef (env, tensor_data);
+ nns_loge ("Failed to allocate memory %zd, index %d.", data_size, i);
+ (*env)->DeleteLocalRef (env, tensor);
failed = TRUE;
goto done;
}
memcpy (data->tensors[i].tensor, data_ptr, data_size);
data->tensors[i].size = data_size;
- (*env)->DeleteLocalRef (env, tensor_data);
+ (*env)->DeleteLocalRef (env, tensor);
}
}
/* parse tensors info in data class */
if (info_h) {
- jmethodID mid_get_info =
- (*env)->GetMethodID (env, pipe_info->cls_tensors_data,
- "getTensorsInfo", "()Lorg/nnsuite/nnstreamer/TensorsInfo;");
- jobject obj_info = (*env)->CallObjectMethod (env, obj_data, mid_get_info);
+ 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);
}
done:
- (*env)->DeleteLocalRef (env, cls_arraylist);
- (*env)->DeleteLocalRef (env, obj_arraylist);
+ (*env)->DeleteLocalRef (env, data_arr);
if (failed) {
ml_tensors_data_destroy (*data_h);
nns_convert_tensors_info (pipeline_info_s * pipe_info, JNIEnv * env,
ml_tensors_info_h info_h, jobject * result)
{
- guint i, j;
+ guint i;
+ info_class_info_s *icls_info;
ml_tensors_info_s *info;
- jmethodID mid_init, mid_add;
jobject obj_info = NULL;
g_return_val_if_fail (pipe_info, 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;
- /* method to generate tensors info */
- mid_init =
- (*env)->GetMethodID (env, pipe_info->cls_tensors_info, "<init>", "()V");
- mid_add =
- (*env)->GetMethodID (env, pipe_info->cls_tensors_info, "appendInfo",
- "(Ljava/lang/String;I[I)V");
-
- obj_info = (*env)->NewObject (env, pipe_info->cls_tensors_info, mid_init);
+ 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;
jstring name = NULL;
jint type;
jintArray dimension;
- jint *dim;
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);
- dim = (*env)->GetIntArrayElements (env, dimension, NULL);
- for (j = 0; j < ML_TENSOR_RANK_LIMIT; j++) {
- dim[j] = (jint) info->info[i].dimension[j];
- }
- (*env)->ReleaseIntArrayElements (env, dimension, dim, 0);
-
- (*env)->CallVoidMethod (env, obj_info, mid_add, name, type, dimension);
+ (*env)->CallVoidMethod (env, obj_info, icls_info->mid_add_info,
+ name, type, dimension);
if (name)
(*env)->DeleteLocalRef (env, name);
nns_parse_tensors_info (pipeline_info_s * pipe_info, JNIEnv * env,
jobject obj_info, ml_tensors_info_h * info_h)
{
- guint i, j;
+ 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);
return FALSE;
}
+ icls_info = &pipe_info->info_cls_info;
info = (ml_tensors_info_s *) (*info_h);
- /* get field 'mInfoList' */
- jfieldID fid_arraylist =
- (*env)->GetFieldID (env, pipe_info->cls_tensors_info, "mInfoList",
- "Ljava/util/ArrayList;");
- jobject obj_arraylist = (*env)->GetObjectField (env, obj_info, fid_arraylist);
-
- /* method to get tensors info */
- jclass cls_arraylist = (*env)->GetObjectClass (env, obj_arraylist);
- jmethodID mid_size = (*env)->GetMethodID (env, cls_arraylist, "size", "()I");
- jmethodID mid_get =
- (*env)->GetMethodID (env, cls_arraylist, "get", "(I)Ljava/lang/Object;");
+ info_arr = (*env)->CallObjectMethod (env, obj_info, icls_info->mid_get_array);
/* number of tensors info */
- info->num_tensors =
- (unsigned int) (*env)->CallIntMethod (env, obj_arraylist, mid_size);
+ info->num_tensors = (unsigned int) (*env)->GetArrayLength (env, info_arr);
/* read tensor info */
for (i = 0; i < info->num_tensors; i++) {
- jobject item = (*env)->CallObjectMethod (env, obj_arraylist, mid_get, i);
- jclass cls_info = (*env)->GetObjectClass (env, item);
-
- jmethodID mid_name =
- (*env)->GetMethodID (env, cls_info, "getName", "()Ljava/lang/String;");
- jmethodID mid_type =
- (*env)->GetMethodID (env, cls_info, "getTypeValue", "()I");
- jmethodID mid_dimension =
- (*env)->GetMethodID (env, cls_info, "getDimension", "()[I");
+ jobject item = (*env)->GetObjectArrayElement (env, info_arr, i);
/* tensor name */
- jstring name_str = (jstring) (*env)->CallObjectMethod (env, item, mid_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);
}
/* tensor type */
- info->info[i].type =
- (ml_tensor_type_e) (*env)->CallIntMethod (env, item, mid_type);
+ info->info[i].type = (ml_tensor_type_e) (*env)->GetIntField (env, item,
+ icls_info->fid_info_type);
/* tensor dimension */
- jintArray dim =
- (jintArray) (*env)->CallObjectMethod (env, item, mid_dimension);
- jsize length = (*env)->GetArrayLength (env, dim);
- jint *dimension = (*env)->GetIntArrayElements (env, dim, NULL);
-
- g_assert (length == ML_TENSOR_RANK_LIMIT);
- for (j = 0; j < length; j++) {
- info->info[i].dimension[j] = (unsigned int) dimension[j];
- }
-
- (*env)->ReleaseIntArrayElements (env, dim, dimension, 0);
- (*env)->DeleteLocalRef (env, dim);
+ 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, cls_info);
(*env)->DeleteLocalRef (env, item);
}
- (*env)->DeleteLocalRef (env, cls_arraylist);
- (*env)->DeleteLocalRef (env, obj_arraylist);
+ (*env)->DeleteLocalRef (env, info_arr);
return TRUE;
}
#include "nnstreamer-native.h"
/**
+ * @brief Private data for CustomFilter class.
+ */
+typedef struct
+{
+ jmethodID mid_invoke;
+ jmethodID mid_info;
+} customfilter_priv_data_s;
+
+/**
* @brief Table to handle custom-filter.
*/
static GHashTable *g_customfilters = NULL;
/**
+ * @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;
+
+ /* nothing to free */
+ g_free (priv);
+}
+
+/**
* @brief The mandatory callback for GstTensorFilterFramework.
* @param prop The property of tensor_filter instance
* @param private_data Sub-plugin's private data
GstTensorMemory * output)
{
pipeline_info_s *pipe_info = NULL;
+ customfilter_priv_data_s *priv;
ml_tensors_data_h in_data, out_data;
ml_tensors_info_h in_info;
ml_tensors_data_s *_data;
JNIEnv *env;
- jclass cls_custom;
- jmethodID mid_invoke;
jobject obj_in_data, obj_out_data;
guint i;
int ret = -1;
in_data = out_data = NULL;
in_info = NULL;
obj_in_data = obj_out_data = NULL;
+ priv = (customfilter_priv_data_s *) pipe_info->priv_data;
if (ml_tensors_data_create_no_alloc (NULL, &in_data) != ML_ERROR_NONE) {
nns_loge ("Failed to create handle for input tensors data.");
goto done;
}
- cls_custom = (*env)->GetObjectClass (env, pipe_info->instance);
- mid_invoke = (*env)->GetMethodID (env, cls_custom, "invoke",
- "(Lorg/nnsuite/nnstreamer/TensorsData;)"
- "Lorg/nnsuite/nnstreamer/TensorsData;");
-
/* convert to c-api data type */
_data = (ml_tensors_data_s *) in_data;
_data->num_tensors = prop->input_meta.num_tensors;
ml_tensors_info_copy_from_gst (in_info, &prop->input_meta);
- /* call invoke callback */
+ /* convert to data object */
if (!nns_convert_tensors_data (pipe_info, env, in_data, in_info,
&obj_in_data)) {
nns_loge ("Failed to convert input data to data-object.");
goto done;
}
- obj_out_data =
- (*env)->CallObjectMethod (env, pipe_info->instance, mid_invoke,
- obj_in_data);
+ /* 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 (!nns_parse_tensors_data (pipe_info, env, obj_out_data, &out_data, NULL)) {
nns_loge ("Failed to parse output data.");
(*env)->DeleteLocalRef (env, obj_in_data);
if (obj_out_data)
(*env)->DeleteLocalRef (env, obj_out_data);
- (*env)->DeleteLocalRef (env, cls_custom);
g_free (in_data);
g_free (out_data);
GstTensorsInfo * out_info)
{
pipeline_info_s *pipe_info = NULL;
+ customfilter_priv_data_s *priv;
ml_tensors_info_h in, out;
jobject obj_in_info, obj_out_info;
JNIEnv *env;
- jclass cls_custom;
- jmethodID mid_info;
int ret = -1;
/* get pipe info and init */
in = out = NULL;
obj_in_info = obj_out_info = NULL;
+ priv = (customfilter_priv_data_s *) pipe_info->priv_data;
if (ml_tensors_info_create (&in) != ML_ERROR_NONE) {
nns_loge ("Failed to create handle for input tensors info.");
goto done;
}
- cls_custom = (*env)->GetObjectClass (env, pipe_info->instance);
- mid_info = (*env)->GetMethodID (env, cls_custom, "getOutputInfo",
- "(Lorg/nnsuite/nnstreamer/TensorsInfo;)"
- "Lorg/nnsuite/nnstreamer/TensorsInfo;");
-
/* convert to c-api data type */
ml_tensors_info_copy_from_gst (in, in_info);
- /* call output info callback */
if (!nns_convert_tensors_info (pipe_info, env, in, &obj_in_info)) {
nns_loge ("Failed to convert input tensors info to data object.");
goto done;
}
- obj_out_info =
- (*env)->CallObjectMethod (env, pipe_info->instance, mid_info,
- obj_in_info);
+ /* call output info callback */
+ obj_out_info = (*env)->CallObjectMethod (env, pipe_info->instance,
+ priv->mid_info, obj_in_info);
+
+ if ((*env)->ExceptionCheck (env)) {
+ nns_loge ("Failed to call the custom-info callback.");
+ (*env)->ExceptionClear (env);
+ goto done;
+ }
if (!nns_parse_tensors_info (pipe_info, env, obj_out_info, &out)) {
nns_loge ("Failed to parse output info.");
(*env)->DeleteLocalRef (env, obj_in_info);
if (obj_out_info)
(*env)->DeleteLocalRef (env, obj_out_info);
- (*env)->DeleteLocalRef (env, cls_custom);
ml_tensors_info_destroy (in);
ml_tensors_info_destroy (out);
jobject thiz, jstring name)
{
pipeline_info_s *pipe_info = NULL;
+ customfilter_priv_data_s *priv;
GstTensorFilterFramework *fw = NULL;
const char *filter_name = (*env)->GetStringUTFChars (env, name, NULL);
g_mutex_unlock (&pipe_info->lock);
+ 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 ";");
+ priv->mid_info = (*env)->GetMethodID (env, pipe_info->cls, "getOutputInfo",
+ "(L" NNS_CLS_TINFO ";)L" NNS_CLS_TINFO ";");
+
+ nns_set_priv_data (pipe_info, priv, nns_customfilter_priv_free);
+
done:
(*env)->ReleaseStringUTFChars (env, name, filter_name);
return CAST_TO_LONG (pipe_info);
#include "nnstreamer-native.h"
/**
+ * @brief Private data for Pipeline class.
+ */
+typedef struct
+{
+ jmethodID mid_state_cb;
+ jmethodID mid_sink_cb;
+} pipeline_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 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;
- JNIEnv *env = nns_get_jni_env (pipe_info);
- if (env == NULL) {
+ if ((env = nns_get_jni_env (pipe_info)) == NULL) {
nns_logw ("Cannot get jni env in the state callback.");
return;
}
- jclass cls_pipeline = (*env)->GetObjectClass (env, pipe_info->instance);
- jmethodID mid_callback =
- (*env)->GetMethodID (env, cls_pipeline, "stateChanged", "(I)V");
- jint new_state = (jint) state;
-
- (*env)->CallVoidMethod (env, pipe_info->instance, mid_callback, new_state);
+ (*env)->CallVoidMethod (env, pipe_info->instance, priv->mid_state_cb,
+ new_state);
if ((*env)->ExceptionCheck (env)) {
nns_loge ("Failed to call the callback method.");
(*env)->ExceptionClear (env);
}
-
- (*env)->DeleteLocalRef (env, cls_pipeline);
}
/**
{
element_data_s *cb_data;
pipeline_info_s *pipe_info;
+ pipeline_priv_data_s *priv;
jobject obj_data = NULL;
JNIEnv *env;
cb_data = (element_data_s *) user_data;
pipe_info = cb_data->pipe_info;
+ 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 sink callback.");
}
if (nns_convert_tensors_data (pipe_info, env, data, info, &obj_data)) {
- /* method for sink callback */
- jclass cls_pipeline = (*env)->GetObjectClass (env, pipe_info->instance);
- jmethodID mid_callback =
- (*env)->GetMethodID (env, cls_pipeline, "newDataReceived",
- "(Ljava/lang/String;Lorg/nnsuite/nnstreamer/TensorsData;)V");
jstring sink_name = (*env)->NewStringUTF (env, cb_data->name);
- (*env)->CallVoidMethod (env, pipe_info->instance, mid_callback, sink_name,
- obj_data);
+ (*env)->CallVoidMethod (env, pipe_info->instance, priv->mid_sink_cb,
+ sink_name, obj_data);
if ((*env)->ExceptionCheck (env)) {
nns_loge ("Failed to call the callback method.");
}
(*env)->DeleteLocalRef (env, sink_name);
- (*env)->DeleteLocalRef (env, cls_pipeline);
(*env)->DeleteLocalRef (env, obj_data);
} else {
nns_loge ("Failed to convert the result to data object.");
return NULL;
}
- status =
- ml_pipeline_sink_register (pipe, element_name, nns_sink_data_cb, item,
- &handle);
+ 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);
(ml_pipeline_switch_h) nns_get_element_handle (pipe_info, element_name);
if (handle == NULL) {
/* get switch handle and register to table */
- status =
- ml_pipeline_switch_get_handle (pipe, element_name, &switch_type,
+ 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);
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);
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,
+ status = ml_pipeline_construct (pipeline, nns_pipeline_state_cb, pipe_info,
&pipe);
else
status = ml_pipeline_construct (pipeline, NULL, NULL, &pipe);
int status;
const char *element_name = (*env)->GetStringUTFChars (env, name, NULL);
char **pad_list = NULL;
- guint i, total = 0;
+ guint i, total;
jobjectArray result = NULL;
pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
goto done;
}
+ total = g_strv_length (pad_list);
+
/* set string array */
- if (pad_list) {
+ if (total > 0) {
jclass cls_string = (*env)->FindClass (env, "java/lang/String");
- while (pad_list[total] != NULL)
- total++;
-
- result =
- (*env)->NewObjectArray (env, total, cls_string,
- (*env)->NewStringUTF (env, ""));
+ result = (*env)->NewObjectArray (env, total, cls_string, NULL);
if (result == NULL) {
nns_loge ("Failed to allocate string array.");
(*env)->DeleteLocalRef (env, cls_string);
}
for (i = 0; i < total; i++) {
- (*env)->SetObjectArrayElement (env, result, i, (*env)->NewStringUTF (env,
- pad_list[i]));
- g_free (pad_list[i]);
- }
+ jstring pad = (*env)->NewStringUTF (env, pad_list[i]);
- g_free (pad_list);
- pad_list = NULL;
+ (*env)->SetObjectArrayElement (env, result, i, pad);
+ (*env)->DeleteLocalRef (env, pad);
+ }
(*env)->DeleteLocalRef (env, cls_string);
}
done:
- /* free pad list */
- if (pad_list) {
- i = 0;
- while (pad_list[i] != NULL) {
- g_free (pad_list[i]);
- }
- g_free (pad_list);
- }
-
+ g_strfreev (pad_list);
(*env)->ReleaseStringUTFChars (env, name, element_name);
return result;
}
models_count = (*env)->GetArrayLength (env, models);
for (i = 0; i < models_count; i++) {
- jstring model_obj =
- (jstring) (*env)->GetObjectArrayElement (env, models, i);
- const char *model_path = (*env)->GetStringUTFChars (env, model_obj, NULL);
+ 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_obj, model_path);
+ (*env)->ReleaseStringUTFChars (env, model, model_path);
+ (*env)->DeleteLocalRef (env, model);
}
info.models = g_string_free (model_str, FALSE);
#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"
+
+/**
+ * @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_element_type_e;
/**
+ * @brief Struct for TensorsData class info.
+ */
+typedef struct
+{
+ jclass cls;
+ jmethodID mid_init;
+ jmethodID mid_add_data;
+ jmethodID mid_get_array;
+ jmethodID mid_set_info;
+ 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
pthread_key_t jni_env;
jobject instance;
- jclass cls_tensors_data;
- jclass cls_tensors_info;
+ 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;
/**
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 handle of given name.
*/
extern gpointer