[Repo] Implement Dynamic Property(slot_id) Change of Repo
authorjijoong.moon <jijoong.moon@samsung.com>
Fri, 18 Jan 2019 08:21:51 +0000 (17:21 +0900)
committerMyungJoo Ham <myungjoo.ham@gmail.com>
Thu, 24 Jan 2019 09:49:00 +0000 (18:49 +0900)
Implement Dynamic slot_id property change of tensor_reposrc and
tensor_reposink. In order to check the status of current repo,
sink_changed(gboolean), sink_id(guint) and src_changed (gboolean),
src_id(guint) variables are added. While waiting buffer from
repo_sink, repo check if this variables are changed using
gst_tensor_repo_check_chagned call, and if it changed, it trys to get
buffer from new slot id. The changing status of repo is set when slot
id property changed using tensor_repo_set_changed.

**Changes proposed in this PR:**
- Added function calls to check and set the changing status of repo.
- Added variables to control flow in each repo.

**Self evaluation:**
1. Build test:  [X]Passed [ ]Failed [ ]Skipped
2. Run test:  [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: jijoong.moon <jijoong.moon@samsung.com>
gst/nnstreamer/tensor_repo.c
gst/nnstreamer/tensor_repo.h
gst/nnstreamer/tensor_reposink/tensor_reposink.c
gst/nnstreamer/tensor_reposink/tensor_reposink.h
gst/nnstreamer/tensor_reposrc/tensor_reposrc.c
gst/nnstreamer/tensor_reposrc/tensor_reposrc.h

index 98a6ffa..c63345d 100644 (file)
@@ -137,10 +137,42 @@ gst_tensor_repo_get_repodata (guint nth)
 }
 
 /**
+ * @brief Set the changing status of repo.
+ */
+gboolean
+gst_tensor_repo_set_changed (guint o_nth, guint nth, gboolean is_sink)
+{
+  gboolean ret = FALSE;
+  GstTensorRepoData *data;
+  GST_TENSOR_REPO_LOCK (o_nth);
+  data = gst_tensor_repo_get_repodata (o_nth);
+
+  if (data) {
+    if (is_sink) {
+      data->sink_changed = TRUE;
+      data->sink_id = nth;
+      if (DBG)
+        GST_DEBUG ("SET sink_changed! @id %d \n", o_nth);
+      GST_TENSOR_REPO_SIGNAL_PULL (o_nth);
+    } else {
+      data->src_changed = TRUE;
+      data->src_id = nth;
+      if (DBG)
+        GST_DEBUG ("SET src_changed! @id %d\n", o_nth);
+      GST_TENSOR_REPO_SIGNAL_PUSH (o_nth);
+    }
+    ret = TRUE;
+  }
+
+  GST_TENSOR_REPO_UNLOCK (o_nth);
+  return ret;
+}
+
+/**
  * @brief add GstTensorRepoData into repo
  */
 gboolean
-gst_tensor_repo_add_repodata (guint nth)
+gst_tensor_repo_add_repodata (guint nth, gboolean is_sink)
 {
   gboolean ret = FALSE;
   GstTensorRepoData *new;
@@ -149,6 +181,14 @@ gst_tensor_repo_add_repodata (guint nth)
   gpointer check = g_hash_table_lookup (_repo.hash, GINT_TO_POINTER (nth));
 
   if (check != NULL) {
+    new = (GstTensorRepoData *) check;
+    if (is_sink)
+      new->sink_changed = FALSE;
+    else
+      new->src_changed = FALSE;
+    new->pushed = FALSE;
+    if (DBG)
+      GST_DEBUG ("SET SINK & SRC Changed FALSE!! @%d\n", nth);
     GST_REPO_UNLOCK ();
     return TRUE;
   }
@@ -159,6 +199,9 @@ gst_tensor_repo_add_repodata (guint nth)
   g_cond_init (&new->cond_push);
   g_cond_init (&new->cond_pull);
   g_mutex_init (&new->lock);
+  new->sink_changed = FALSE;
+  new->src_changed = FALSE;
+  new->pushed = FALSE;
 
   ret = g_hash_table_insert (_repo.hash, GINT_TO_POINTER (nth), new);
   g_assert (ret);
@@ -175,7 +218,8 @@ gst_tensor_repo_add_repodata (guint nth)
  * @brief push GstBuffer into repo
  */
 gboolean
-gst_tensor_repo_set_buffer (guint nth, GstBuffer * buffer, GstCaps * caps)
+gst_tensor_repo_set_buffer (guint nth, guint o_nth, GstBuffer * buffer,
+    GstCaps * caps)
 {
   GST_TENSOR_REPO_LOCK (nth);
 
@@ -221,6 +265,33 @@ gst_tensor_repo_check_eos (guint nth)
 }
 
 /**
+ * @brief check eos of slot
+ */
+gboolean
+gst_tensor_repo_check_changed (guint nth, guint * newid, gboolean is_sink)
+{
+  gboolean ret = FALSE;
+  GstTensorRepoData *data = gst_tensor_repo_get_repodata (nth);
+  if (DBG)
+    GST_DEBUG ("%dth RepoData : sink_chaned %d, src_changed %d\n", nth,
+        data->sink_changed, data->src_changed);
+
+  if (is_sink) {
+    if (data->sink_changed) {
+      *newid = data->sink_id;
+      ret = data->sink_changed;
+    }
+  } else {
+    if (data->src_changed) {
+      *newid = data->src_id;
+      ret = data->src_changed;
+    }
+  }
+  return ret;
+}
+
+
+/**
  * @brief set eos of slot
  */
 gboolean
@@ -239,33 +310,37 @@ gst_tensor_repo_set_eos (guint nth)
  * @brief get GstTensorRepoData from repo
  */
 GstBuffer *
-gst_tensor_repo_get_buffer (guint nth)
+gst_tensor_repo_get_buffer (guint nth, guint o_nth, gboolean * eos,
+    guint * newid)
 {
   GstTensorRepoData *current_data;
   GstBuffer *buf;
-  gboolean eos = FALSE;
 
   GST_TENSOR_REPO_LOCK (nth);
   current_data = gst_tensor_repo_get_repodata (nth);
 
   while (!current_data->buffer) {
+    if (gst_tensor_repo_check_changed (nth, newid, FALSE)) {
+      buf = NULL;
+      goto done;
+    }
+
     if (gst_tensor_repo_check_eos (nth)) {
-      eos = TRUE;
-      break;
+      *eos = TRUE;
+      buf = NULL;
+      goto done;
     }
     GST_TENSOR_REPO_WAIT_PUSH (nth);
   }
-  if (eos) {
-    if (DBG)
-      GST_DEBUG ("Get EOS Signal while waiting\n");
-    buf = NULL;
-  } else {
-    buf = gst_buffer_copy_deep (current_data->buffer);
-    if (DBG) {
-      unsigned long size = gst_buffer_get_size (buf);
-      GST_DEBUG ("Popped [ %d ] (size: %lu)\n", nth, size);
-    }
+
+  buf = gst_buffer_copy_deep (current_data->buffer);
+  gst_buffer_unref (current_data->buffer);
+  if (DBG) {
+    unsigned long size = gst_buffer_get_size (buf);
+    GST_DEBUG ("Popped [ %d ] (size: %lu)\n", nth, size);
   }
+
+done:
   current_data->buffer = NULL;
   GST_TENSOR_REPO_SIGNAL_PULL (nth);
   GST_TENSOR_REPO_UNLOCK (nth);
index 5d2740d..dfe9512 100644 (file)
@@ -85,6 +85,11 @@ typedef struct
   GCond cond_pull;
   GMutex lock;
   gboolean eos;
+  gboolean src_changed;
+  guint src_id;
+  gboolean sink_changed;
+  guint sink_id;
+  gboolean pushed;
 } GstTensorRepoData;
 
 /**
@@ -110,13 +115,13 @@ gst_tensor_repo_get_repodata (guint nth);
  */
 /* guint */
 gboolean
-gst_tensor_repo_add_repodata (guint myid);
+gst_tensor_repo_add_repodata (guint myid, gboolean is_sink);
 
 /**
  * @brief push GstBuffer into repo
  */
 gboolean
-gst_tensor_repo_set_buffer (guint nth, GstBuffer * buffer, GstCaps * caps);
+gst_tensor_repo_set_buffer (guint nth, guint o_nth, GstBuffer * buffer, GstCaps * caps);
 
 /**
  * @brief get EOS
@@ -130,11 +135,17 @@ gst_tensor_repo_check_eos(guint nth);
 gboolean
 gst_tensor_repo_set_eos(guint nth);
 
+gboolean
+gst_tensor_repo_set_changed(guint o_nth, guint nth, gboolean is_sink);
+
 /**
  * @brief Get GstTensorRepoData from repo
  */
 GstBuffer *
-gst_tensor_repo_get_buffer (guint nth);
+gst_tensor_repo_get_buffer (guint nth, guint o_nth, gboolean *eos, guint *newid);
+
+gboolean
+gst_tensor_repo_check_changed (guint nth, guint *newid, gboolean is_sink);
 
 /**
  * @brief remove nth GstTensorRepoData from GstTensorRepo
index 03a158e..359ce00 100644 (file)
@@ -157,6 +157,7 @@ gst_tensor_reposink_init (GstTensorRepoSink * self)
   self->silent = DEFAULT_SILENT;
   self->signal_rate = DEFAULT_SIGNAL_RATE;
   self->last_render_time = GST_CLOCK_TIME_NONE;
+  self->set_startid = FALSE;
   self->in_caps = NULL;
 
   gst_base_sink_set_qos_enabled (basesink, DEFAULT_QOS);
@@ -180,8 +181,16 @@ gst_tensor_reposink_set_property (GObject * object, guint prop_id,
       self->silent = g_value_get_boolean (value);
       break;
     case PROP_SLOT:
+      self->o_myid = self->myid;
       self->myid = g_value_get_uint (value);
-      gst_tensor_repo_add_repodata (self->myid);
+      gst_tensor_repo_add_repodata (self->myid, TRUE);
+      if (!self->set_startid) {
+        self->o_myid = self->myid;
+        self->set_startid = TRUE;
+      }
+      if (self->o_myid != self->myid)
+        gst_tensor_repo_set_changed (self->o_myid, self->myid, TRUE);
+
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -334,7 +343,9 @@ gst_tensor_reposink_render_buffer (GstTensorRepoSink * self, GstBuffer * buffer)
   if (notify) {
     gboolean ret = FALSE;
     self->last_render_time = now;
-    ret = gst_tensor_repo_set_buffer (self->myid, buffer, self->in_caps);
+    ret =
+        gst_tensor_repo_set_buffer (self->myid, self->o_myid, buffer,
+        self->in_caps);
     if (!ret)
       GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
           ("Cannot Set buffer into repo [key: %d]", self->myid), NULL);
index 704f454..86e5ee4 100644 (file)
@@ -59,7 +59,9 @@ struct _GstTensorRepoSink
   guint signal_rate;
   GstClockTime last_render_time;
   GstCaps *in_caps;
+  gboolean set_startid;
   guint myid;
+  guint o_myid;
 };
 
 /**
index 3c9c275..04ddde6 100644 (file)
@@ -131,6 +131,7 @@ gst_tensor_reposrc_init (GstTensorRepoSrc * self)
   self->negotiation = FALSE;
   gst_tensors_config_init (&self->config);
   self->caps = NULL;
+  self->set_startid = FALSE;
 }
 
 /**
@@ -210,8 +211,19 @@ gst_tensor_reposrc_set_property (GObject * object, guint prop_id,
       self->silent = g_value_get_boolean (value);
       break;
     case PROP_SLOT_ID:
+      self->o_myid = self->myid;
       self->myid = g_value_get_uint (value);
       self->negotiation = FALSE;
+
+      gst_tensor_repo_add_repodata (self->myid, FALSE);
+
+      if (!self->set_startid) {
+        self->o_myid = self->myid;
+        self->set_startid = TRUE;
+      }
+      if (self->o_myid != self->myid)
+        gst_tensor_repo_set_changed (self->o_myid, self->myid, FALSE);
+
       break;
     case PROP_CAPS:
     {
@@ -272,6 +284,30 @@ gst_tensor_reposrc_get_property (GObject * object, guint prop_id,
 }
 
 /**
+ * @brief create dummy buffer for initialization
+ */
+static GstBuffer *
+gst_tensor_reposrc_gen_dummy_buffer (GstTensorRepoSrc * self)
+{
+  GstBuffer *buf = NULL;
+  int i;
+  guint num_tensors = self->config.info.num_tensors;
+  gsize size = 0;
+  buf = gst_buffer_new ();
+  for (i = 0; i < num_tensors; i++) {
+    GstMemory *mem;
+    GstMapInfo info;
+    size = gst_tensor_info_get_size (&self->config.info.info[i]);
+    mem = gst_allocator_alloc (NULL, size, NULL);
+    gst_memory_map (mem, &info, GST_MAP_WRITE);
+    memset (info.data, 0, size);
+    gst_memory_unmap (mem, &info);
+    gst_buffer_append_memory (buf, mem);
+  }
+  return buf;
+}
+
+/**
  * @brief create func of tensor_reposrc
  */
 static GstFlowReturn
@@ -279,35 +315,26 @@ gst_tensor_reposrc_create (GstPushSrc * src, GstBuffer ** buffer)
 {
   GstTensorRepoSrc *self;
   GstBuffer *buf = NULL;
+  gboolean eos = FALSE;
+  GstMetaRepo *meta;
+  guint newid;
 
   self = GST_TENSOR_REPOSRC (src);
   gst_tensor_repo_wait ();
 
   if (!self->ini) {
-    int i;
-    guint num_tensors = self->config.info.num_tensors;
-    gsize size = 0;
-    buf = gst_buffer_new ();
-    for (i = 0; i < num_tensors; i++) {
-      GstMemory *mem;
-      GstMapInfo info;
-      size = gst_tensor_info_get_size (&self->config.info.info[i]);
-      mem = gst_allocator_alloc (NULL, size, NULL);
-      gst_memory_map (mem, &info, GST_MAP_WRITE);
-      memset (info.data, 0, size);
-      gst_memory_unmap (mem, &info);
-      gst_buffer_append_memory (buf, mem);
-    }
+    buf = gst_tensor_reposrc_gen_dummy_buffer (self);
     self->ini = TRUE;
   } else {
-    buf = gst_tensor_repo_get_buffer (self->myid);
-
-    if (buf == NULL)
+    while (!buf && !eos) {
+      buf = gst_tensor_repo_get_buffer (self->myid, self->o_myid, &eos, &newid);
+    }
+    if (eos)
       return GST_FLOW_EOS;
 
-    GstMetaRepo *meta = GST_META_REPO_GET (buf);
+    meta = GST_META_REPO_GET (buf);
 
-    if (!self->negotiation) {
+    if (!self->negotiation && buf != NULL) {
       if (!gst_caps_can_intersect (self->caps, meta->caps)) {
         GST_ELEMENT_ERROR (GST_ELEMENT (self), CORE, NEGOTIATION,
             ("Negotiation Failed! : repo_sink & repos_src"), (NULL));
@@ -318,8 +345,8 @@ gst_tensor_reposrc_create (GstPushSrc * src, GstBuffer ** buffer)
       }
 
       self->negotiation = TRUE;
-    }
 
+    }
     gst_buffer_remove_meta (buf, (GstMeta *) meta);
   }
 
index 748bdde..3c81de1 100644 (file)
@@ -56,10 +56,12 @@ struct _GstTensorRepoSrc
   GstTensorsConfig config;
   gboolean silent;
   guint myid;
+  guint o_myid;
   GstCaps *caps;
   gboolean ini;
   gint fps_n, fps_d;
   gboolean negotiation;
+  gboolean set_startid;
 };
 
 /**