Update custom-filter API using custom-easy.
- register custom-filter with in/out info and implement invoke interface only.
Signed-off-by: Jaeyun <jy1210.jung@samsung.com>
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.registerCustomFilter("custom-passthrough",
- new CustomFilter.CustomFilterCallback() {
- @Override
- public TensorsInfo getOutputInfo(TensorsInfo in) {
- return in;
- }
-
- @Override
- public TensorsData invoke(TensorsData in) {
- return in;
- }
- });
+ inputInfo, outputInfo, new CustomFilter.CustomFilterCallback() {
+ @Override
+ public TensorsData invoke(TensorsData in) {
+ return in;
+ }
+ });
/* register custom-filter (convert data type to float) */
+ outputInfo.setTensorType(0, NNStreamer.TensorType.FLOAT32);
mCustomConvert = CustomFilter.registerCustomFilter("custom-convert",
- new CustomFilter.CustomFilterCallback() {
- @Override
- public TensorsInfo getOutputInfo(TensorsInfo in) {
- in.setTensorType(0, NNStreamer.TensorType.FLOAT32);
- return in;
- }
-
- @Override
- public TensorsData invoke(TensorsData in) {
- TensorsInfo info = in.getTensorsInfo();
- ByteBuffer input = in.getTensorData(0);
+ inputInfo, outputInfo, new CustomFilter.CustomFilterCallback() {
+ @Override
+ public TensorsData invoke(TensorsData in) {
+ TensorsInfo info = in.getTensorsInfo();
+ ByteBuffer input = in.getTensorData(0);
- info.setTensorType(0, NNStreamer.TensorType.FLOAT32);
+ info.setTensorType(0, NNStreamer.TensorType.FLOAT32);
- TensorsData out = info.allocate();
- ByteBuffer output = out.getTensorData(0);
+ 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;
+ 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.registerCustomFilter("custom-add",
- new CustomFilter.CustomFilterCallback() {
- @Override
- public TensorsInfo getOutputInfo(TensorsInfo in) {
- return in;
- }
+ inputInfo, outputInfo, new CustomFilter.CustomFilterCallback() {
+ @Override
+ public TensorsData invoke(TensorsData in) {
+ TensorsInfo info = in.getTensorsInfo();
+ ByteBuffer input = in.getTensorData(0);
- @Override
- public TensorsData invoke(TensorsData in) {
- TensorsInfo info = in.getTensorsInfo();
- ByteBuffer input = in.getTensorData(0);
+ TensorsData out = info.allocate();
+ ByteBuffer output = out.getTensorData(0);
- TensorsData out = info.allocate();
- ByteBuffer output = out.getTensorData(0);
+ for (int i = 0; i < 10; i++) {
+ float value = input.getFloat(i * 4);
- 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;
+ /* add constant */
+ value += 1.5f;
+ output.putFloat(i * 4, value);
}
- });
+
+ out.setTensorData(0, output);
+ return out;
+ }
+ });
mRegistered = true;
} catch (Exception e) {
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=" + mCustomPassthrough.getName() + " ! " +
- "tensor_filter framework=" + mCustomConvert.getName() + " ! " +
- "tensor_filter framework=" + mCustomAdd.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)) {
@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.registerCustomFilter("custom-drop",
- new CustomFilter.CustomFilterCallback() {
+ inputInfo, outputInfo, new CustomFilter.CustomFilterCallback() {
int received = 0;
@Override
- public TensorsInfo getOutputInfo(TensorsInfo in) {
- return in;
- }
-
- @Override
public TensorsData invoke(TensorsData in) {
received++;
String desc = "appsrc name=srcx ! " +
"other/tensor,dimension=(string)10:1:1:1,type=(string)int32,framerate=(fraction)0/1 ! " +
- "tensor_filter framework=" + customDrop.getName() + " ! " +
- "tensor_filter framework=" + mCustomPassthrough.getName() + " ! " +
- "tensor_filter framework=" + mCustomConvert.getName() + " ! " +
- "tensor_filter framework=" + mCustomAdd.getName() + " ! " +
+ "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)) {
@Test
public void testRegisterNullName_n() {
+ TensorsInfo inputInfo = new TensorsInfo();
+ inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
+
+ TensorsInfo outputInfo = inputInfo.clone();
+
try {
- CustomFilter.registerCustomFilter(null,
- new CustomFilter.CustomFilterCallback() {
- @Override
- public TensorsInfo getOutputInfo(TensorsInfo in) {
- return in;
- }
+ CustomFilter.registerCustomFilter(null, inputInfo, outputInfo,
+ new CustomFilter.CustomFilterCallback() {
+ @Override
+ public TensorsData invoke(TensorsData in) {
+ return in;
+ }
+ });
- @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.registerCustomFilter("custom-invalid-info", null, outputInfo,
+ new CustomFilter.CustomFilterCallback() {
+ @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.registerCustomFilter("custom-invalid-info", inputInfo, null,
+ new CustomFilter.CustomFilterCallback() {
+ @Override
+ public TensorsData invoke(TensorsData in) {
+ return in;
+ }
});
fail();
@Test
public void testRegisterNullCallback_n() {
+ TensorsInfo inputInfo = new TensorsInfo();
+ inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
+
+ TensorsInfo outputInfo = inputInfo.clone();
+
try {
- CustomFilter.registerCustomFilter("custom-invalid-cb", null);
+ CustomFilter.registerCustomFilter("custom-invalid-cb", inputInfo, outputInfo, null);
+
fail();
} catch (Exception e) {
/* expected */
@Test
public void testRegisterDuplicatedName_n() {
- try {
- CustomFilter.registerCustomFilter(mCustomPassthrough.getName(),
- new CustomFilter.CustomFilterCallback() {
- @Override
- public TensorsInfo getOutputInfo(TensorsInfo in) {
- return in;
- }
+ TensorsInfo inputInfo = new TensorsInfo();
+ inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
- @Override
- public TensorsData invoke(TensorsData in) {
- return in;
- }
- });
+ TensorsInfo outputInfo = inputInfo.clone();
+
+ try {
+ CustomFilter.registerCustomFilter(mCustomPassthrough.getName(), inputInfo, outputInfo,
+ new CustomFilter.CustomFilterCallback() {
+ @Override
+ public TensorsData invoke(TensorsData in) {
+ return in;
+ }
+ });
fail();
} catch (Exception e) {
@Test
public void testRegisterPreservedName_n() {
- try {
- CustomFilter.registerCustomFilter("auto",
- new CustomFilter.CustomFilterCallback() {
- @Override
- public TensorsInfo getOutputInfo(TensorsInfo in) {
- return in;
- }
+ TensorsInfo inputInfo = new TensorsInfo();
+ inputInfo.addTensorInfo(NNStreamer.TensorType.INT32, new int[]{10});
- @Override
- public TensorsData invoke(TensorsData in) {
- return in;
- }
- });
+ TensorsInfo outputInfo = inputInfo.clone();
+
+ try {
+ CustomFilter.registerCustomFilter("auto", inputInfo, outputInfo,
+ new CustomFilter.CustomFilterCallback() {
+ @Override
+ public TensorsData invoke(TensorsData in) {
+ return in;
+ }
+ });
fail();
} catch (Exception e) {
/**
* Provides interfaces to create a custom-filter in the pipeline.<br>
* <br>
- * To register a new custom-filter, an application should call {@link #registerCustomFilter(String, CustomFilterCallback)}
+ * To register a new custom-filter, an application should call
+ * {@link #registerCustomFilter(String, TensorsInfo, TensorsInfo, CustomFilterCallback)}
* before constructing the pipeline.
*/
public final class CustomFilter implements AutoCloseable {
private String mName = null;
private CustomFilterCallback mCallback = null;
- private native long nativeInitialize(String name);
+ 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 #registerCustomFilter(String, CustomFilterCallback)
+ * @see #registerCustomFilter(String, TensorsInfo, TensorsInfo, CustomFilterCallback)
*/
public interface CustomFilterCallback {
/**
- * Called synchronously when constructing a pipeline.
- *
- * NNStreamer filter configures input and output tensors information during the caps negotiation.
- *
- * Note that this is not a fixed value and the pipeline may try different values during the caps negotiation.
- * An application should validate the information of input tensors and return proper output information.
- *
- * @param in The input tensors information
- *
- * @return The output tensors information
- */
- TensorsInfo getOutputInfo(TensorsInfo in);
-
- /**
* Called synchronously while processing the pipeline.
*
* NNStreamer filter invokes the given custom-filter callback while processing the pipeline.
}
/**
- * Registers new custom-filter with name.
+ * Registers 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, 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 null
* @throws IllegalStateException if failed to initialize custom-filter
*/
- public static CustomFilter registerCustomFilter(@NonNull String name, @NonNull CustomFilterCallback callback) {
- return new CustomFilter(name, callback);
+ public static CustomFilter registerCustomFilter(@NonNull String name, @NonNull TensorsInfo in,
+ @NonNull TensorsInfo out, @NonNull CustomFilterCallback callback) {
+ return new CustomFilter(name, in, out, callback);
}
/**
* 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 null
* @throws IllegalStateException if failed to initialize custom-filter
*/
- private CustomFilter(@NonNull String name, @NonNull CustomFilterCallback callback) {
+ private CustomFilter(String name, TensorsInfo in, TensorsInfo out, CustomFilterCallback 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);
+ mHandle = nativeInitialize(name, in, out);
if (mHandle == 0) {
throw new IllegalStateException("Failed to initialize custom-filter " + name);
}
}
/**
- * Internal method called from native during the caps negotiation.
- */
- private TensorsInfo getOutputInfo(TensorsInfo in) {
- TensorsInfo out = null;
-
- if (mCallback != null) {
- out = mCallback.getOutputInfo(in);
- }
-
- return out;
- }
-
- /**
* Internal method called from native while processing the pipeline.
*/
private TensorsData invoke(TensorsData in) {
ml_pipeline_destroy (pipe_info->pipeline_handle);
break;
case NNS_PIPE_TYPE_CUSTOM:
- /**
- * Do nothing here (no handle to close).
- * The handle is filter-framework and it will be closed in customfilter-destroy function.
- */
+ ml_pipeline_custom_easy_filter_unregister (pipe_info->pipeline_handle);
break;
#endif
case NNS_PIPE_TYPE_SINGLE:
g_return_val_if_fail (obj_data, FALSE);
g_return_val_if_fail (data_h, FALSE);
- if (ml_tensors_data_create_no_alloc (NULL, data_h) != ML_ERROR_NONE) {
+ 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;
}
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)
+ data->tensors[i].tensor = g_malloc (data_size);
if (data->tensors[i].tensor == NULL) {
nns_loge ("Failed to allocate memory %zd, index %d.", data_size, i);
(*env)->DeleteLocalRef (env, tensor);
* @brief List of implemented native methods for CustomFilter class.
*/
static JNINativeMethod native_methods_customfilter[] = {
- {"nativeInitialize", "(Ljava/lang/String;)J",
+ {"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}
};
typedef struct
{
jmethodID mid_invoke;
- jmethodID mid_info;
ml_tensors_info_h in_info;
jobject in_info_obj;
} customfilter_priv_data_s;
/**
- * @brief Table to handle custom-filter.
- */
-static GHashTable *g_customfilters = NULL;
-
-/**
* @brief Release private data in custom filter.
*/
static void
}
/**
- * @brief The mandatory callback for GstTensorFilterFramework.
- * @param prop The property of tensor_filter instance
- * @param private_data Sub-plugin's private data
- * @param[in] input The array of input tensors
- * @param[out] output The array of output tensors
- * @return 0 if OK. Non-zero if error.
+ * @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 GstTensorFilterProperties * prop,
- void **private_data, const GstTensorMemory * input,
- GstTensorMemory * output)
+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;
- ml_tensors_data_h in_data, out_data;
- ml_tensors_info_h in_info;
- ml_tensors_data_s *_data;
JNIEnv *env;
jobject obj_in_data, obj_out_data;
- guint i;
int ret = -1;
/* get pipe info and init */
- pipe_info = g_hash_table_lookup (g_customfilters, prop->fwname);
+ 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);
- 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;
- }
-
- if (ml_tensors_info_create (&in_info) != ML_ERROR_NONE) {
- nns_loge ("Failed to create handle for input tensors info.");
- goto done;
- }
-
- /* convert to c-api data type */
- _data = (ml_tensors_data_s *) in_data;
- _data->num_tensors = prop->input_meta.num_tensors;
- for (i = 0; i < _data->num_tensors; i++) {
- _data->tensors[i].tensor = input[i].data;
- _data->tensors[i].size = input[i].size;
- }
-
- ml_tensors_info_copy_from_gst (in_info, &prop->input_meta);
- if (!nns_customfilter_priv_set_in_info (pipe_info, env, in_info)) {
- goto done;
- }
-
/* convert to data object */
- if (!nns_convert_tensors_data (pipe_info, env, in_data, priv->in_info_obj,
+ 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;
goto done;
}
- if (!nns_parse_tensors_data (pipe_info, env, obj_out_data, &out_data, NULL)) {
+ if (!nns_parse_tensors_data (pipe_info, env, obj_out_data, &out, NULL)) {
nns_loge ("Failed to parse output data.");
goto done;
}
- /* set output data */
- _data = (ml_tensors_data_s *) out_data;
- for (i = 0; i < _data->num_tensors; i++) {
- output[i].data = _data->tensors[i].tensor;
-
- if (_data->tensors[i].size != output[i].size) {
- nns_logw ("The result has different buffer size at index %d [%zd:%zd]",
- i, output[i].size, _data->tensors[i].size);
- output[i].size = _data->tensors[i].size;
- }
- }
-
/* callback finished */
ret = 0;
if (obj_out_data)
(*env)->DeleteLocalRef (env, obj_out_data);
- g_free (in_data);
- g_free (out_data);
- ml_tensors_info_destroy (in_info);
return ret;
}
/**
- * @brief The optional callback for GstTensorFilterFramework.
- * @param prop The property of tensor_filter instance
- * @param private_data Sub-plugin's private data
- * @param[in] in_info The dimension and type of input tensors
- * @param[out] out_info The dimension and type of output tensors
- * @return 0 if OK. Non-zero if error.
+ * @brief Native method for custom filter.
*/
-static int
-nns_customfilter_set_dimension (const GstTensorFilterProperties * prop,
- void **private_data, const GstTensorsInfo * in_info,
- GstTensorsInfo * out_info)
+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_tensors_info_h in, out;
- jobject obj_in_info, obj_out_info;
- JNIEnv *env;
- int ret = -1;
+ 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);
- /* get pipe info and init */
- pipe_info = g_hash_table_lookup (g_customfilters, prop->fwname);
- g_return_val_if_fail (pipe_info, -1);
+ nns_logd ("Try to add custom-filter %s.", model_name);
+ in_info = out_info = NULL;
- env = nns_get_jni_env (pipe_info);
- g_return_val_if_fail (env, -1);
-
- 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.");
+ 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;
}
- /* convert to c-api data type */
- ml_tensors_info_copy_from_gst (in, in_info);
-
- 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;
- }
+ 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);
- /* call output info callback */
- obj_out_info = (*env)->CallObjectMethod (env, pipe_info->instance,
- priv->mid_info, obj_in_info);
+ nns_set_priv_data (pipe_info, priv, nns_customfilter_priv_free);
- if ((*env)->ExceptionCheck (env)) {
- nns_loge ("Failed to call the custom-info callback.");
- (*env)->ExceptionClear (env);
+ 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, obj_out_info, &out)) {
+ if (!nns_parse_tensors_info (pipe_info, env, out, &out_info)) {
nns_loge ("Failed to parse output info.");
goto done;
}
- /* set output data */
- ml_tensors_info_copy_from_ml (out_info, out);
-
- /* callback finished */
- ret = 0;
-
-done:
- if (obj_in_info)
- (*env)->DeleteLocalRef (env, obj_in_info);
- if (obj_out_info)
- (*env)->DeleteLocalRef (env, obj_out_info);
-
- ml_tensors_info_destroy (in);
- ml_tensors_info_destroy (out);
- return ret;
-}
-
-/**
- * @brief Native method for custom filter.
- */
-jlong
-nns_native_custom_initialize (JNIEnv * env, 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);
-
- nns_logd ("Try to add custom-filter %s.", filter_name);
-
- if (nnstreamer_filter_find (filter_name)) {
- nns_logw ("Custom-filter %s already exists.", filter_name);
- goto done;
- }
-
- /* prepare filter-framework */
- fw = g_new0 (GstTensorFilterFramework, 1);
- if (fw == NULL) {
- nns_loge ("Failed to allocate memory for filter framework.");
+ /* update input info */
+ if (!nns_customfilter_priv_set_in_info (pipe_info, env, in_info)) {
goto done;
}
- fw->version = GST_TENSOR_FILTER_FRAMEWORK_V0;
- fw->name = g_strdup (filter_name);
- fw->allocate_in_invoke = TRUE;
- fw->run_without_model = TRUE;
- fw->invoke_NN = nns_customfilter_invoke;
- fw->setInputDimension = nns_customfilter_set_dimension;
-
- /* register custom-filter */
- if (!nnstreamer_filter_probe (fw)) {
- nns_loge ("Failed to register custom-filter %s.", filter_name);
- g_free (fw->name);
- g_free (fw);
+ 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 = nns_construct_pipe_info (env, thiz, fw, NNS_PIPE_TYPE_CUSTOM);
- if (pipe_info == NULL) {
- nns_loge ("Failed to create pipe info.");
- nnstreamer_filter_exit (fw->name);
- g_free (fw->name);
- g_free (fw);
- goto done;
- }
+ pipe_info->pipeline_handle = custom;
+ is_done = TRUE;
- /* add custom-filter handle to the table */
- g_mutex_lock (&pipe_info->lock);
+done:
+ (*env)->ReleaseStringUTFChars (env, name, model_name);
- if (g_customfilters == NULL) {
- g_customfilters =
- g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ if (!is_done) {
+ nns_destroy_pipe_info (pipe_info, env);
+ pipe_info = NULL;
}
- g_assert (g_hash_table_insert (g_customfilters, g_strdup (filter_name),
- pipe_info));
-
- 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 ";");
- ml_tensors_info_create (&priv->in_info);
-
- nns_set_priv_data (pipe_info, priv, nns_customfilter_priv_free);
-
-done:
- (*env)->ReleaseStringUTFChars (env, name, filter_name);
return CAST_TO_LONG (pipe_info);
}
nns_native_custom_destroy (JNIEnv * env, jobject thiz, jlong handle)
{
pipeline_info_s *pipe_info = NULL;
- GstTensorFilterFramework *fw = NULL;
pipe_info = CAST_TO_TYPE (handle, pipeline_info_s *);
- g_return_if_fail (pipe_info);
-
- fw = (GstTensorFilterFramework *) pipe_info->pipeline_handle;
- nns_logd ("Start to unregister custom-filter %s.", fw->name);
-
- g_mutex_lock (&pipe_info->lock);
- if (!g_hash_table_remove (g_customfilters, fw->name)) {
- nns_logw ("Failed to remove custom-filter %s.", fw->name);
- }
- g_mutex_unlock (&pipe_info->lock);
-
- nnstreamer_filter_exit (fw->name);
- g_free (fw->name);
- g_free (fw);
-
nns_destroy_pipe_info (pipe_info, env);
}
nns_native_single_set_input_info (JNIEnv * env, jobject thiz, jlong handle, jobject in);
#if !defined (NNS_SINGLE_ONLY)
extern jlong
-nns_native_custom_initialize (JNIEnv * env, jobject thiz, jstring name);
+nns_native_custom_initialize (JNIEnv * env, jobject thiz, jstring name, jobject in, jobject out);
extern void
nns_native_custom_destroy (JNIEnv * env, jobject thiz, jlong handle);
extern jlong