[C-Api] fix invalid sink handle
authorJaeyun <jy1210.jung@samsung.com>
Thu, 14 Nov 2019 08:21:38 +0000 (17:21 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Fri, 15 Nov 2019 08:27:37 +0000 (17:27 +0900)
When trying to register sink callbacks to same sink element, it returns null handler.
To fix this, allocate new handle and add it  into the handle list.

Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
api/capi/src/nnstreamer-capi-pipeline.c
tests/tizen_capi/unittest_tizen_capi.cpp

index f085831..b21f3c3 100644 (file)
@@ -829,32 +829,27 @@ ml_pipeline_sink_register (ml_pipeline_h pipe, const char *sink_name,
   }
 
   if (elem->handle_id > 0) {
+    /* no need to connect signal to sink element */
     ml_logw ("Sink callback is already registered.");
-    ret = ML_ERROR_NONE;
-    goto unlock_return;
-  }
-
-  /* set callback for new data */
-  if (elem->type == ML_PIPELINE_ELEMENT_SINK) {
-    /* tensor_sink */
-    g_object_set (G_OBJECT (elem->element), "emit-signal", (gboolean) TRUE,
-        NULL);
-    elem->handle_id =
-        g_signal_connect (elem->element, "new-data", G_CALLBACK (cb_sink_event),
-        elem);
   } else {
-    /* appsink */
-    g_object_set (G_OBJECT (elem->element), "emit-signals", (gboolean) TRUE,
-        NULL);
-    elem->handle_id =
-        g_signal_connect (elem->element, "new-sample",
-        G_CALLBACK (cb_appsink_new_sample), elem);
-  }
+    /* set callback for new data */
+    if (elem->type == ML_PIPELINE_ELEMENT_SINK) {
+      /* tensor_sink */
+      g_object_set (G_OBJECT (elem->element), "emit-signal", (gboolean) TRUE, NULL);
+      elem->handle_id = g_signal_connect (elem->element, "new-data",
+          G_CALLBACK (cb_sink_event), elem);
+    } else {
+      /* appsink */
+      g_object_set (G_OBJECT (elem->element), "emit-signals", (gboolean) TRUE, NULL);
+      elem->handle_id = g_signal_connect (elem->element, "new-sample",
+          G_CALLBACK (cb_appsink_new_sample), elem);
+    }
 
-  if (elem->handle_id == 0) {
-    ml_loge ("Failed to connect a signal to the element [%s].", sink_name);
-    ret = ML_ERROR_STREAMS_PIPE;
-    goto unlock_return;
+    if (elem->handle_id == 0) {
+      ml_loge ("Failed to connect a signal to the element [%s].", sink_name);
+      ret = ML_ERROR_STREAMS_PIPE;
+      goto unlock_return;
+    }
   }
 
   sink = *h = g_new0 (ml_pipeline_sink, 1);
@@ -948,8 +943,8 @@ ml_pipeline_src_parse_tensors_info (ml_pipeline_element * elem)
       } else {
         if (!elem->is_media_stream) {
           ml_logw
-            ("Cannot find caps. The pipeline is not yet negotiated for src element [%s].",
-            elem->name);
+              ("Cannot find caps. The pipeline is not yet negotiated for src element [%s].",
+              elem->name);
           gst_object_unref (elem->src);
           elem->src = NULL;
           ret = ML_ERROR_TRY_AGAIN;
@@ -1085,7 +1080,7 @@ ml_pipeline_src_input_data (ml_pipeline_src_h h, ml_tensors_data_h data,
     goto destroy_data;
   }
 
-  if (!elem->is_media_stream){
+  if (!elem->is_media_stream) {
     if (elem->tensors_info.num_tensors != _data->num_tensors) {
       ml_loge
           ("The src push of [%s] cannot be handled because the number of tensors in a frame mismatches. %u != %u",
index f7eab72..9671cc6 100644 (file)
@@ -513,6 +513,8 @@ TEST (nnstreamer_capi_sink, dummy_01)
   EXPECT_EQ (status, ML_ERROR_NONE);
 
   status = ml_pipeline_sink_register (handle, "sinkx", test_sink_callback_dm01, file2, &sinkhandle);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (sinkhandle != NULL);
 
   status = ml_pipeline_start (handle);
   EXPECT_EQ (status, ML_ERROR_NONE);
@@ -575,6 +577,7 @@ TEST (nnstreamer_capi_sink, dummy_02)
 
   status = ml_pipeline_sink_register (handle, "sinkx", test_sink_callback_count, count_sink, &sinkhandle);
   EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (sinkhandle != NULL);
 
   status = ml_pipeline_start (handle);
   EXPECT_EQ (status, ML_ERROR_NONE);
@@ -609,6 +612,68 @@ TEST (nnstreamer_capi_sink, dummy_02)
 
 /**
  * @brief Test NNStreamer pipeline sink
+ */
+TEST (nnstreamer_capi_sink, register_duplicated)
+{
+  ml_pipeline_h handle;
+  ml_pipeline_sink_h sinkhandle0, sinkhandle1;
+  gchar *pipeline;
+  int status;
+  guint *count_sink0, *count_sink1;
+  TestPipeState *pipe_state;
+
+  /* pipeline with appsink */
+  pipeline = g_strdup ("videotestsrc num-buffers=3 ! videoconvert ! tensor_converter ! appsink name=sinkx");
+
+  count_sink0 = (guint *) g_malloc (sizeof (guint));
+  ASSERT_TRUE (count_sink0 != NULL);
+  *count_sink0 = 0;
+
+  count_sink1 = (guint *) g_malloc (sizeof (guint));
+  ASSERT_TRUE (count_sink1 != NULL);
+  *count_sink1 = 0;
+
+  pipe_state = (TestPipeState *) g_new0 (TestPipeState, 1);
+  ASSERT_TRUE (pipe_state != NULL);
+
+  status = ml_pipeline_construct (pipeline, test_pipe_state_callback, pipe_state, &handle);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_pipeline_sink_register (handle, "sinkx", test_sink_callback_count, count_sink0, &sinkhandle0);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (sinkhandle0 != NULL);
+
+  status = ml_pipeline_sink_register (handle, "sinkx", test_sink_callback_count, count_sink1, &sinkhandle1);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (sinkhandle1 != NULL);
+
+  status = ml_pipeline_start (handle);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  g_usleep (100000); /* 100ms. Let a few frames flow. */
+
+  status = ml_pipeline_sink_unregister (sinkhandle0);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_pipeline_sink_unregister (sinkhandle1);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_pipeline_destroy (handle);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  EXPECT_TRUE (*count_sink0 > 0U);
+  EXPECT_TRUE (*count_sink1 > 0U);
+  EXPECT_TRUE (pipe_state->paused);
+  EXPECT_TRUE (pipe_state->playing);
+
+  g_free (pipeline);
+  g_free (count_sink0);
+  g_free (count_sink1);
+  g_free (pipe_state);
+}
+
+/**
+ * @brief Test NNStreamer pipeline sink
  * @detail Failure case to register callback with invalid param.
  */
 TEST (nnstreamer_capi_sink, failure_01_n)
@@ -654,6 +719,7 @@ TEST (nnstreamer_capi_sink, failure_01_n)
 
   status = ml_pipeline_sink_register (handle, "sinkx", test_sink_callback_count, count_sink, &sinkhandle);
   EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (sinkhandle != NULL);
 
   status = ml_pipeline_start (handle);
   EXPECT_EQ (status, ML_ERROR_NONE);
@@ -984,6 +1050,7 @@ TEST (nnstreamer_capi_switch, dummy_01)
 
   status = ml_pipeline_sink_register (handle, "sinkx", test_sink_callback_count, count_sink, &sinkhandle);
   EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (sinkhandle != NULL);
 
   status = ml_pipeline_switch_select (switchhandle, "sink_1");
   EXPECT_EQ (status, ML_ERROR_NONE);
@@ -1077,9 +1144,11 @@ TEST (nnstreamer_capi_switch, dummy_02)
 
   status = ml_pipeline_sink_register (handle, "sink0", test_sink_callback_count, count_sink0, &sinkhandle0);
   EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (sinkhandle0 != NULL);
 
   status = ml_pipeline_sink_register (handle, "sink1", test_sink_callback_count, count_sink1, &sinkhandle1);
   EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (sinkhandle1 != NULL);
 
   status = ml_pipeline_switch_select (switchhandle, "src_1");
   EXPECT_EQ (status, ML_ERROR_NONE);