[Filter/Main] Guarantee calling "open" before all other callbacks.
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Fri, 22 Jun 2018 07:23:49 +0000 (16:23 +0900)
committer함명주/동작제어Lab(SR)/Principal Engineer/삼성전자 <myungjoo.ham@samsung.com>
Wed, 27 Jun 2018 11:01:56 +0000 (20:01 +0900)
Added "open" virtual methods for tensor_filer subplugins.

TODO: guarantee calling "close" at the end.

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

index 4cea2d9..88d0325 100644 (file)
@@ -250,6 +250,8 @@ gst_tensor_filter_init (GstTensor_Filter * filter)
   filter->prop.silent = TRUE;
   filter->prop.nnfw = _T_F_UNDEFINED;
   filter->prop.fw = NULL;
+  filter->prop.fwOpened = FALSE;
+  filter->prop.fwClosed = FALSE;
   filter->prop.inputConfigured = _TFC_INIT;
   filter->prop.outputConfigured = _TFC_INIT;
   filter->prop.modelFilename = NULL;
@@ -273,6 +275,33 @@ gst_tensor_filter_init (GstTensor_Filter * filter)
 }
 
 /**
+ * @brief Invoke callbacks of filter->prop.fw. Gurantees calling open for the first call.
+ */
+#define gst_tensor_filter_call(filter, funcname, ...) ({ \
+    int __ret = 0; \
+    do { \
+      if (filter->prop.fwOpened == FALSE) { \
+        if (filter->prop.fw->open != NULL) \
+          filter->prop.fw->open(filter, &filter->privateData); \
+       filter->prop.fwOpened = TRUE; \
+      } \
+      g_assert(filter->prop.fwClosed != TRUE); \
+      __ret = filter->prop.fw->funcname(filter, &filter->privateData, __VA_ARGS__); \
+    } while(0); \
+    __ret; \
+})
+
+/* @TODO Call this where appropriate */
+#define gst_tensor_filter_close(filter) \
+    do { \
+      g_assert(filter->prop.fwClosed != TRUE); \
+      g_assert(filter->prop.fwOpened == TRUE); \
+      if (filter->prop.fw->close) \
+        filter->prop.fw->close(filter, &filter->privateData); \
+      filter->prop.fw->fwClosed = TRUE; \
+    } while (0);
+
+/**
  * @brief Calculate the rank of a tensor
  * @param dimension The dimension vector (tensor_dim = uint32_t[NNS_TENSOR_RANK_LIMIT]) of tensor.
  * @return the rank value
@@ -417,7 +446,7 @@ gst_tensor_filter_check_consistency_fw (GstTensor_Filter * filter,
     return TRUE;                /* Nothing to check. FW is not configured, yet */
 
   if (checkInput == TRUE && fw->getInputDimension != NULL) {
-    ret = fw->getInputDimension (filter, &filter->privateData, dim, &type);
+    ret = gst_tensor_filter_call (filter, getInputDimension, dim, &type);
     if (ret) {
       debug_print (TRUE,
           "getInputDimension failed (%d). But we can continue with it.\n", ret);
@@ -433,7 +462,7 @@ gst_tensor_filter_check_consistency_fw (GstTensor_Filter * filter,
   }
 
   if (checkOutput == TRUE && fw->getOutputDimension != NULL) {
-    ret = fw->getOutputDimension (filter, &filter->privateData, dim, &type);
+    ret = gst_tensor_filter_call (filter, getOutputDimension, dim, &type);
     if (ret) {
       debug_print (TRUE,
           "getOutputDimension failed (%d). But we can continue with it.\n",
@@ -665,7 +694,6 @@ gst_tensor_filter_transform (GstBaseTransform * trans,
     GstBuffer * inbuf, GstBuffer * outbuf)
 {
   GstTensor_Filter *filter = GST_TENSOR_FILTER_CAST (trans);
-  GstTensor_Filter_Framework *func;
   int ret;
   size_t outBufSize;
   uint8_t *inptr, *outptr;
@@ -684,7 +712,6 @@ gst_tensor_filter_transform (GstBaseTransform * trans,
   /* 0. Check all properties and inbuf size. */
   debug_print (!filter->prop.silent, "Invoking %s with %s model\n",
       filter->prop.fw->name, filter->prop.modelFilename);
-  func = filter->prop.fw;
 
   g_assert (filter->prop.inputConfigured & _TFC_ALL &&
       filter->prop.outputConfigured & _TFC_ALL);
@@ -704,7 +731,7 @@ gst_tensor_filter_transform (GstBaseTransform * trans,
   inptr = inInfo.data;
   outptr = outInfo.data;
 
-  ret = func->invoke_NN (filter, &filter->privateData, inptr, outptr);
+  ret = gst_tensor_filter_call (filter, invoke_NN, inptr, outptr);
 
   gst_buffer_unmap (inbuf, &inInfo);
   gst_buffer_unmap (outbuf, &outInfo);
@@ -766,7 +793,7 @@ gst_tensor_filter_property_process (GstTensor_Filter * filter)
   if (fw->getInputDimension != NULL) {
     g_assert (fw->getOutputDimension != NULL);
 
-    ret = fw->getInputDimension (filter, &filter->privateData, dim, &type);
+    ret = gst_tensor_filter_call (filter, getInputDimension, dim, &type);
     if (ret) {
       err_print ("getInputDimension() returns %d. Cannot proceed.\n", ret);
       return -1;
@@ -781,7 +808,7 @@ gst_tensor_filter_property_process (GstTensor_Filter * filter)
       prop->inputConfigured |= _TFC_DIMENSION;
     }
 
-    ret = fw->getOutputDimension (filter, &filter->privateData, dim, &type);
+    ret = gst_tensor_filter_call (filter, getOutputDimension, dim, &type);
     if (ret) {
       err_print ("getOutputDimension() returns %d. Cannot proceed.\n", ret);
       return -1;
index 0b3ed0a..27ed0b7 100644 (file)
@@ -169,7 +169,8 @@ struct _GstTensor_Filter_Framework
        * If this is non-NULL, both getInput/OutputDimension must be NULL.
        */
 
-  void (*close)(const GstTensor_Filter *filter, void **private_data); /**< Optional. Close this instance! Free-ing private_data is this function's responsibility. Set NULL after that. */
+  void (*open)(const GstTensor_Filter *filter, void **private_data); /**< Optional. tensor_filter.c will call this before any of other callbacks and will call once before calling close */
+  void (*close)(const GstTensor_Filter *filter, void **private_data); /**< Optional. tensor_filter.c will not call other callbacks after calling close. Free-ing private_data is this function's responsibility. Set NULL after that. */
 };
 
 extern GstTensor_Filter_Framework NNS_support_tensorflow_lite;
index 224cfcc..dc8c1ab 100644 (file)
@@ -116,6 +116,8 @@ typedef struct _GstTensor_Filter_Properties
   GstTensor_Filter_CheckStatus outputConfigured; /** < output dimension status */
   nnfw_type nnfw; /**< The enum value of corresponding NNFW. _T_F_UNDEFINED if not configured */
   GstTensor_Filter_Framework *fw; /**< The implementation core of the NNFW. NULL if not configured */
+  int fwOpened; /**< true IF open() is called or tried. Use int instead of gboolean because this is refered by custom plugins. */
+  int fwClosed; /**< true IF close() is called or tried. Use int instead of gboolean because this is refered by custom plugins. */
   const char *modelFilename; /**< Filepath to the model file (as an argument for NNFW). char instead of gchar for non-glib custom plugins */
 
   tensor_dim inputDimension; /**< The input tensor dimension */