[Example/CustomFilter/Test] change custom passthrough filter
authorJaeyun <jy1210.jung@samsung.com>
Thu, 20 Sep 2018 07:40:05 +0000 (16:40 +0900)
committerMyungJoo Ham <myungjoo.ham@gmail.com>
Fri, 21 Sep 2018 05:32:45 +0000 (14:32 +0900)
1. change custom passthrough example to support multi tensors
2. add simple stream testcases for multi tensors

Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
nnstreamer_example/custom_example_passthrough/nnstreamer_customfilter_example_passthrough_variable.c
tests/nnstreamer_filter_custom/runTest.sh
tests/nnstreamer_sink/unittest_sink.cpp

index c4afd25..febb352 100644 (file)
@@ -32,6 +32,7 @@ static void *
 pt_init (const GstTensorFilterProperties * prop)
 {
   pt_data *data = (pt_data *) malloc (sizeof (pt_data));
+  g_assert (data);
 
   data->id = 0;
   return data;
@@ -55,17 +56,20 @@ static int
 set_inputDim (void *private_data, const GstTensorFilterProperties * prop,
     const GstTensorsInfo * in_info, GstTensorsInfo * out_info)
 {
-  int i;
+  int i, t;
 
   g_assert (in_info);
   g_assert (out_info);
 
-  out_info->num_tensors = 1;
+  out_info->num_tensors = in_info->num_tensors;
 
-  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++)
-    out_info->info[0].dimension[i] = in_info->info[0].dimension[i];
+  for (t = 0; t < in_info->num_tensors; t++) {
+    for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+      out_info->info[t].dimension[i] = in_info->info[t].dimension[i];
+    }
 
-  out_info->info[0].type = in_info->info[0].type;
+    out_info->info[t].type = in_info->info[t].type;
+  }
 
   return 0;
 }
@@ -79,16 +83,19 @@ pt_invoke (void *private_data, const GstTensorFilterProperties * prop,
 {
   pt_data *data = private_data;
   size_t size;
+  int t;
 
   g_assert (data);
   g_assert (input);
   g_assert (output);
 
-  size = get_tensor_element_count (prop->output_meta.info[0].dimension) *
-      tensor_element_size[prop->output_meta.info[0].type];
+  for (t = 0; t < prop->output_meta.num_tensors; t++) {
+    size = get_tensor_element_count (prop->output_meta.info[t].dimension) *
+        tensor_element_size[prop->output_meta.info[t].type];
 
-  g_assert (input[0].data != output[0].data);
-  memcpy (output[0].data, input[0].data, size);
+    g_assert (input[t].data != output[t].data);
+    memcpy (output[t].data, input[t].data, size);
+  }
 
   return 0;
 }
index 055fbf1..4a42bf2 100755 (executable)
@@ -35,10 +35,15 @@ gstTest "--gst-plugin-path=${PATH_TO_PLUGIN} videotestsrc num-buffers=1 ! video/
 
 compareAll testcase03.direct.log testcase03.passthrough.log 3
 
-gstTest "--gst-plugin-path=${PATH_TO_PLUGIN} videotestsrc num-buffers=1 ! video/x-raw,format=RGB,width=640,height=480,framerate=0/1 ! videoconvert ! video/x-raw, format=RGB ! tensor_converter ! tee name=t ! queue ! tensor_filter framework=\"custom\" model=\"${PATH_TO_MODEL_V}\" ! filesink location=\"testcase04.passthrough.log\" sync=true t. ! queue ! filesink location=\"testcase04.direct.log\" sync=true" 4
+# Test single tensor (other/tensor)
+gstTest "--gst-plugin-path=${PATH_TO_PLUGIN} videotestsrc num-buffers=1 ! video/x-raw,format=RGB,width=640,height=480,framerate=0/1 ! videoconvert ! video/x-raw, format=RGB ! tensor_converter ! tee name=t ! queue ! tensor_filter framework=\"custom\" model=\"${PATH_TO_MODEL_V}\" ! filesink location=\"testcase04.tensor.passthrough.log\" sync=true t. ! queue ! filesink location=\"testcase04.tensor.direct.log\" sync=true" 4-1
 
-compareAll testcase04.direct.log testcase04.passthrough.log 4
+compareAll testcase04.tensor.direct.log testcase04.tensor.passthrough.log 4-2
 
+# Test multi tensors with mux (other/tensors)
+gstTest "--gst-plugin-path=${PATH_TO_PLUGIN} tensor_mux name=mux ! tee name=t ! queue ! tensor_filter framework=\"custom\" model=\"${PATH_TO_MODEL_V}\" ! filesink location=\"testcase04.tensors.passthrough.log\" sync=true t. ! queue ! filesink location=\"testcase04.tensors.direct.log\" sync=true videotestsrc num-buffers=1 ! video/x-raw,format=RGB,width=160,height=120,framerate=0/1 ! tensor_converter ! mux.sink_0 videotestsrc num-buffers=1 ! video/x-raw,format=RGB,width=120,height=80,framerate=0/1 ! tensor_converter ! mux.sink_1 videotestsrc num-buffers=1 ! video/x-raw,format=RGB,width=64,height=48,framerate=0/1 ! tensor_converter ! mux.sink_2" 4-3
+
+compareAll testcase04.tensors.direct.log testcase04.tensors.passthrough.log 4-4
 
 # Test scaler (5, 6, 7)
 PATH_TO_MODEL_S="../../build/nnstreamer_example/custom_example_scaler/libnnstreamer_customfilter_scaler.so"
index 471cfbd..f2a6f4a 100644 (file)
@@ -67,11 +67,13 @@ typedef enum
   TEST_TYPE_TEXT, /**< pipeline for text */
   TEST_TYPE_TEXT_3F, /**< pipeline for text 3 frames */
   TEST_TYPE_TENSORS, /**< pipeline for tensors with tensor_mux */
+  TEST_TYPE_CUSTOM_TENSOR, /**< pipeline for single tensor with passthrough custom filter */
+  TEST_TYPE_CUSTOM_TENSORS, /**< pipeline for tensors with passthrough custom filter */
   TEST_TYPE_NEGO_FAILED, /**< pipeline to test caps negotiation */
-  TEST_TYPE_VIDEO_RGB_AGGR, /**< pipeline to test tensor-aggregator */
-  TEST_TYPE_AUDIO_S16_AGGR, /**< pipeline to test tensor-aggregator */
-  TEST_TYPE_AUDIO_U16_AGGR, /**< pipeline to test tensor-aggregator */
-  TEST_TYPE_TYPECAST, /**< pipeline for typecast with tensor-transform */
+  TEST_TYPE_VIDEO_RGB_AGGR, /**< pipeline to test tensor_aggregator */
+  TEST_TYPE_AUDIO_S16_AGGR, /**< pipeline to test tensor_aggregator */
+  TEST_TYPE_AUDIO_U16_AGGR, /**< pipeline to test tensor_aggregator */
+  TEST_TYPE_TYPECAST, /**< pipeline for typecast with tensor_transform */
   TEST_TYPE_UNKNOWN /**< unknonwn */
 } TestType;
 
@@ -187,7 +189,7 @@ _new_data_cb (GstElement * element, GstBuffer * buffer, gpointer user_data)
     }
 
     if (g_test_data.received_size != buf_size) {
-      _print_log ("invalid size, old[%d] new[%d]", g_test_data.received_size,
+      _print_log ("invalid size, old[%zd] new[%zd]", g_test_data.received_size,
           buf_size);
       g_assert (0);
     }
@@ -442,9 +444,27 @@ _setup_pipeline (TestOption & option)
           g_strdup_printf
           ("tensor_mux name=mux ! tensor_sink name=test_sink "
           "videotestsrc num-buffers=%d ! video/x-raw,width=160,height=120,format=RGB,framerate=(fraction)30/1 ! tensor_converter ! mux.sink_0 "
-          "videotestsrc num-buffers=%d ! video/x-raw,width=160,height=120,format=RGB,framerate=(fraction)30/1 ! tensor_converter ! mux.sink_1 ",
+          "videotestsrc num-buffers=%d ! video/x-raw,width=160,height=120,format=RGB,framerate=(fraction)30/1 ! tensor_converter ! mux.sink_1",
           option.num_buffers, option.num_buffers);
       break;
+    case TEST_TYPE_CUSTOM_TENSOR:
+      /** video 160x120 RGB, passthrough custom filter */
+      str_pipeline =
+          g_strdup_printf
+          ("videotestsrc num-buffers=%d ! videoconvert ! video/x-raw,width=160,height=120,format=RGB,framerate=(fraction)30/1 ! "
+          "tensor_converter ! tensor_filter framework=custom model=./nnstreamer_example/custom_example_passthrough/libnnstreamer_customfilter_passthrough_variable.so ! tensor_sink name=test_sink",
+          option.num_buffers);
+      break;
+    case TEST_TYPE_CUSTOM_TENSORS:
+      /** other/tensors with tensormux, passthrough custom filter */
+      str_pipeline =
+          g_strdup_printf
+          ("tensor_mux name=mux ! tensor_filter framework=custom model=./nnstreamer_example/custom_example_passthrough/libnnstreamer_customfilter_passthrough_variable.so ! tensor_sink name=test_sink "
+          "videotestsrc num-buffers=%d ! video/x-raw,width=160,height=120,format=RGB,framerate=(fraction)30/1 ! tensor_converter ! mux.sink_0 "
+          "videotestsrc num-buffers=%d ! video/x-raw,width=120,height=80,format=RGB,framerate=(fraction)30/1 ! tensor_converter ! mux.sink_1 "
+          "videotestsrc num-buffers=%d ! video/x-raw,width=64,height=48,format=RGB,framerate=(fraction)30/1 ! tensor_converter ! mux.sink_2",
+          option.num_buffers, option.num_buffers, option.num_buffers);
+      break;
     case TEST_TYPE_NEGO_FAILED:
       /** caps negotiation failed */
       str_pipeline =
@@ -734,7 +754,7 @@ TEST (tensor_sink_test, caps_tensors)
   /** check received buffers */
   EXPECT_EQ (g_test_data.received, num_buffers);
   EXPECT_EQ (g_test_data.mem_blocks, 2);
-  EXPECT_EQ (g_test_data.received_size, 115200);
+  EXPECT_EQ (g_test_data.received_size, 115200); /** 160 * 120 * 3 * 2 */
 
   /** check caps name */
   EXPECT_TRUE (g_str_equal (g_test_data.caps_name, "other/tensors"));
@@ -1118,7 +1138,7 @@ TEST (tensor_stream_test, audio_s8)
 /**
  * @brief Test for audio format U8, 100 frames from tensor_converter.
  */
-TEST (tensor_stream_test, audio_u8_100F)
+TEST (tensor_stream_test, audio_u8_100f)
 {
   const guint num_buffers = 5; /** 5 * 500 frames */
   TestOption option = { num_buffers, TEST_TYPE_AUDIO_U8_100F };
@@ -1314,6 +1334,129 @@ TEST (tensor_stream_test, text_utf8_3f)
 }
 
 /**
+ * @brief Test for other/tensor, passthrough custom filter.
+ */
+TEST (tensor_stream_test, custom_filter_tensor)
+{
+  const guint num_buffers = 5;
+  TestOption option = { num_buffers, TEST_TYPE_CUSTOM_TENSOR };
+
+  ASSERT_TRUE (_setup_pipeline (option));
+
+  gst_element_set_state (g_test_data.pipeline, GST_STATE_PLAYING);
+  g_main_loop_run (g_test_data.loop);
+  gst_element_set_state (g_test_data.pipeline, GST_STATE_NULL);
+
+  /** check eos message */
+  EXPECT_EQ (g_test_data.status, TEST_EOS);
+
+  /** check received buffers */
+  EXPECT_EQ (g_test_data.received, num_buffers);
+  EXPECT_EQ (g_test_data.mem_blocks, 1);
+  EXPECT_EQ (g_test_data.received_size, 57600);
+
+  /** check caps name */
+  EXPECT_TRUE (g_str_equal (g_test_data.caps_name, "other/tensor"));
+
+  /** check tensor config for video */
+  EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.tensor_config));
+  EXPECT_EQ (g_test_data.tensor_config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.tensor_config.info.dimension[0], 3);
+  EXPECT_EQ (g_test_data.tensor_config.info.dimension[1], 160);
+  EXPECT_EQ (g_test_data.tensor_config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.tensor_config.info.dimension[3], 1);
+  EXPECT_EQ (g_test_data.tensor_config.rate_n, 30);
+  EXPECT_EQ (g_test_data.tensor_config.rate_d, 1);
+
+  /** check caps and config for tensor */
+  {
+    GstCaps *caps;
+    GstStructure *structure;
+    GstTensorConfig config;
+
+    caps = gst_tensor_caps_from_config (&g_test_data.tensor_config);
+    structure = gst_caps_get_structure (caps, 0);
+
+    EXPECT_TRUE (gst_tensor_config_from_structure (&config, structure));
+    EXPECT_TRUE (gst_tensor_config_is_equal (&config,
+            &g_test_data.tensor_config));
+
+    gst_caps_unref (caps);
+  }
+
+  _free_test_data ();
+}
+
+/**
+ * @brief Test for other/tensors, passthrough custom filter.
+ */
+TEST (tensor_stream_test, custom_filter_tensors)
+{
+  const guint num_buffers = 5;
+  TestOption option = { num_buffers, TEST_TYPE_CUSTOM_TENSORS };
+
+  ASSERT_TRUE (_setup_pipeline (option));
+
+  gst_element_set_state (g_test_data.pipeline, GST_STATE_PLAYING);
+  g_main_loop_run (g_test_data.loop);
+  gst_element_set_state (g_test_data.pipeline, GST_STATE_NULL);
+
+  /** check eos message */
+  EXPECT_EQ (g_test_data.status, TEST_EOS);
+
+  /** check received buffers */
+  EXPECT_EQ (g_test_data.received, num_buffers);
+  EXPECT_EQ (g_test_data.mem_blocks, 3);
+  EXPECT_EQ (g_test_data.received_size, 95616); /** 160 * 120 * 3 + 120 * 80 * 3 + 64 * 48 * 3 */
+
+  /** check caps name */
+  EXPECT_TRUE (g_str_equal (g_test_data.caps_name, "other/tensors"));
+
+  /** check tensors config for video */
+  EXPECT_TRUE (gst_tensors_config_validate (&g_test_data.tensors_config));
+  EXPECT_EQ (g_test_data.tensors_config.info.num_tensors, 3);
+
+  EXPECT_EQ (g_test_data.tensors_config.info.info[0].type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[0].dimension[0], 3);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[0].dimension[1], 160);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[0].dimension[2], 120);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[0].dimension[3], 1);
+
+  EXPECT_EQ (g_test_data.tensors_config.info.info[1].type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[1].dimension[0], 3);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[1].dimension[1], 120);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[1].dimension[2], 80);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[1].dimension[3], 1);
+
+  EXPECT_EQ (g_test_data.tensors_config.info.info[2].type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[2].dimension[0], 3);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[2].dimension[1], 64);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[2].dimension[2], 48);
+  EXPECT_EQ (g_test_data.tensors_config.info.info[2].dimension[3], 1);
+
+  EXPECT_EQ (g_test_data.tensors_config.rate_n, 30);
+  EXPECT_EQ (g_test_data.tensors_config.rate_d, 1);
+
+  /** check caps and config for tensors */
+  {
+    GstCaps *caps;
+    GstStructure *structure;
+    GstTensorsConfig config;
+
+    caps = gst_tensors_caps_from_config (&g_test_data.tensors_config);
+    structure = gst_caps_get_structure (caps, 0);
+
+    EXPECT_TRUE (gst_tensors_config_from_structure (&config, structure));
+    EXPECT_TRUE (gst_tensors_config_is_equal (&config,
+            &g_test_data.tensors_config));
+
+    gst_caps_unref (caps);
+  }
+
+  _free_test_data ();
+}
+
+/**
  * @brief Test for typecast to int32 using tensor_transform.
  */
 TEST (tensor_stream_test, typecast_int32)