[Filter] Support pipeviz with tensor_filter
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Mon, 12 Nov 2018 08:11:49 +0000 (17:11 +0900)
committerjaeyun-jung <39614140+jaeyun-jung@users.noreply.github.com>
Wed, 14 Nov 2018 07:41:11 +0000 (16:41 +0900)
1. Make "open" vmethod to return status. Handle
the error if "open" returns "fail". Don't die with assert.

2. Handle inappropriate property values. Don't die with such.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
gst/tensor_filter/tensor_filter.c
gst/tensor_filter/tensor_filter.h
gst/tensor_filter/tensor_filter_custom.c
gst/tensor_filter/tensor_filter_tensorflow.c
gst/tensor_filter/tensor_filter_tensorflow_lite.c

index ff10b60..e90756a 100644 (file)
@@ -204,9 +204,14 @@ static gboolean gst_tensor_filter_stop (GstBaseTransform * trans);
  */
 #define gst_tensor_filter_open_fw(filter) do { \
       if (filter->prop.fw_opened == FALSE) { \
-        if (filter->fw->open != NULL) \
-          filter->fw->open (filter, &filter->privateData); \
-        filter->prop.fw_opened = TRUE; \
+        if (filter->fw->open != NULL) {\
+          if (filter->fw->open (filter, &filter->privateData) == 0) \
+            filter->prop.fw_opened = TRUE; \
+          else \
+            filter->prop.fw_opened = FALSE; \
+        } else {\
+          filter->prop.fw_opened = TRUE; \
+        } \
       } \
     } while (0)
 
@@ -225,6 +230,10 @@ static gboolean gst_tensor_filter_stop (GstBaseTransform * trans);
  */
 #define gst_tensor_filter_call(filter,ret,funcname,...) do { \
       gst_tensor_filter_open_fw (filter); \
+      if (filter->prop.fw_opened == FALSE) { \
+        ret = -1; \
+        break; \
+      } \
       ret = filter->fw->funcname (filter, &filter->privateData, __VA_ARGS__); \
     } while (0)
 
@@ -396,13 +405,26 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
       silent_debug ("Debug mode = %d", self->silent);
       break;
     case PROP_FRAMEWORK:
-      g_assert (prop->nnfw == _T_F_UNDEFINED && value);
-      /* Once configures, it cannot be changed in runtime */
+      if (prop->nnfw != _T_F_UNDEFINED) {
+        /** @todo CRITICAL: CLOSE IT before proceeding */
+        if (prop->fw_opened == TRUE)
+          gst_tensor_filter_close_fw (self);
+      }
       prop->nnfw = find_key_strv (nnfw_names, g_value_get_string (value));
       silent_debug ("Framework = %s\n", g_value_get_string (value));
-      g_assert (prop->nnfw != -1);
-      g_assert (prop->nnfw != _T_F_UNDEFINED);
-      g_assert (tensor_filter_supported[prop->nnfw] != NULL);
+      if (prop->nnfw == -1 || prop->nnfw == _T_F_UNDEFINED) {
+        GST_WARNING ("Cannot identify the given neural network framework, %s\n",
+            g_value_get_string (value));
+        prop->nnfw = _T_F_UNDEFINED;
+        break;
+      }
+      if (tensor_filter_supported[prop->nnfw] == NULL) {
+        GST_WARNING
+            ("The given neural network framework is identified but not supported, %s\n",
+            g_value_get_string (value));
+        prop->nnfw = _T_F_UNDEFINED;
+        break;
+      }
       self->fw = tensor_filter_supported[prop->nnfw];
       g_assert (self->fw != NULL);
 
@@ -412,7 +434,15 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
           || self->fw->setInputDimension);
       break;
     case PROP_MODEL:
-      g_assert (prop->model_file == NULL && value);
+      if (prop->model_file) {
+        /** @todo CRITICAL: CLOSE IT before proceeding */
+        if (prop->fw_opened == TRUE)
+          gst_tensor_filter_close_fw (self);
+        g_free ((char *) prop->model_file);     /* g_free cannot handle const * */
+      }
+      if (!value) {
+        break;
+      }
       /* Once configures, it cannot be changed in runtime */
       tmp = g_value_dup_string (value);
       silent_debug ("Model = %s\n", tmp);
@@ -504,8 +534,8 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
       }
       break;
     case PROP_CUSTOM:
-      g_assert (prop->custom_properties == NULL && value);
-      /* Once configures, it cannot be changed in runtime */
+      /* In case updated custom properties in runtime! */
+      g_free ((char *) prop->custom_properties);        /* g_free cannot handle const char * */
       prop->custom_properties = g_value_dup_string (value);
       silent_debug ("Custom Option = %s\n", prop->custom_properties);
       break;
index 0d01b18..83527f3 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <stdint.h>
 #include <gst/gst.h>
+#include <gst/gstinfo.h>
 #include <gst/base/gstbasetransform.h>
 #include <tensor_common.h>
 
@@ -165,11 +166,12 @@ struct _GstTensorFilterFramework
        * @return 0 if OK. non-zero if error.
        */
 
-  void (*open) (const GstTensorFilter * filter, void **private_data);
+  int (*open) (const GstTensorFilter * filter, void **private_data);
       /**< Optional. tensor_filter.c will call this before any of other callbacks and will call once before calling close
        *
        * @param[in] filter "this" pointer. Use this to read property values
        * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. Normally, open() allocates memory for private_data.
+       * @return 0 if ok. < 0 if error.
        */
 
   void (*close) (const GstTensorFilter * filter, void **private_data);
index d69752f..cb10efe 100644 (file)
@@ -60,6 +60,11 @@ custom_loadlib (const GstTensorFilter * filter, void **private_data)
     return 1;
   }
 
+  if (!filter->prop.model_file || filter->prop.model_file[0] == '\0') {
+    /* The .so file path is not given */
+    return -1;
+  }
+
   ptr = g_new0 (internal_data, 1);      /* Fill Zero! */
   *private_data = ptr;
   g_assert (*private_data == filter->privateData);
@@ -99,19 +104,22 @@ custom_loadlib (const GstTensorFilter * filter, void **private_data)
 /**
  * @brief The open callback for GstTensorFilterFramework. Called before anything else
  */
-static void
+static int
 custom_open (const GstTensorFilter * filter, void **private_data)
 {
   int retval = custom_loadlib (filter, private_data);
   internal_data *ptr;
 
-  g_assert (retval == 0);       /* This must be called only once */
+  /* This must be called only once */
+  if (retval != 0)
+    return -1;
 
   ptr = *private_data;
   g_assert (!ptr->methods->invoke != !ptr->methods->allocate_invoke);   /* XOR! */
 
   if (ptr->methods->allocate_invoke)
     NNS_support_custom.allocate_in_invoke = TRUE;
+  return 0;
 }
 
 /**
index dadf085..6b78cf0 100644 (file)
@@ -68,11 +68,12 @@ tf_loadModelFile (const GstTensorFilter * filter, void **private_data)
  * @param filter : tensor_filter instance
  * @param private_data : tensorflow lite plugin's private data
  */
-static void
+static int
 tf_open (const GstTensorFilter * filter, void **private_data)
 {
   int retval = tf_loadModelFile (filter, private_data);
   g_assert (retval == 0);       /** This must be called only once */
+  return 0;
 }
 
 /**
index da29337..571be2b 100644 (file)
@@ -68,11 +68,12 @@ tflite_loadModelFile (const GstTensorFilter * filter, void **private_data)
  * @param filter : tensor_filter instance
  * @param private_data : tensorflow lite plugin's private data
  */
-static void
+static int
 tflite_open (const GstTensorFilter * filter, void **private_data)
 {
   int retval = tflite_loadModelFile (filter, private_data);
   g_assert (retval == 0);       /** This must be called only once */
+  return 0;
 }
 
 /**