[Filter/Test] flow-return to drop incoming buffer
authorJaeyun <jy1210.jung@samsung.com>
Fri, 25 Jan 2019 04:58:55 +0000 (13:58 +0900)
committerwooksong <wook16.song@samsung.com>
Fri, 25 Jan 2019 08:27:09 +0000 (17:27 +0900)
check returned value from invoke vmethod and return flow-dropped to skip incoming buffer.

TODO:
define status code for NNFW and custom-filter

Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
gst/nnstreamer/tensor_filter/tensor_filter.c
tests/meson.build
tests/nnstreamer_sink/nnscustom_drop_buffer.c [new file with mode: 0644]
tests/nnstreamer_sink/unittest_sink.cpp

index ddf3787..3c54766 100644 (file)
@@ -904,7 +904,8 @@ gst_tensor_filter_transform (GstBaseTransform * trans,
 
   /* 3. Call the filter-subplugin callback, "invoke" */
   gst_tensor_filter_call (self, ret, invoke_NN, in_tensors, out_tensors);
-  g_assert (ret == 0);
+  /** @todo define enum to indicate status code */
+  g_assert (ret >= 0);
 
   /* 4. Update result and free map info. */
   for (i = 0; i < prop->output_meta.num_tensors; i++) {
@@ -927,6 +928,12 @@ gst_tensor_filter_transform (GstBaseTransform * trans,
   }
 
   /* 5. Return result! */
+  if (ret > 0) {
+    /** @todo define enum to indicate status code */
+    /* drop this buffer */
+    return GST_BASE_TRANSFORM_FLOW_DROPPED;
+  }
+
   return GST_FLOW_OK;
 unknown_format:
   GST_ELEMENT_ERROR (self, CORE, NOT_IMPLEMENTED, (NULL), ("unknown format"));
index b9d1ac9..e780fb5 100644 (file)
@@ -11,13 +11,19 @@ library('tensorscheck',
   install: false
 )
 
-# This custom filter is used in unittest_sink.
+# These custom filters are used in unittest_sink.
 library('nnscustom_framecounter',
   join_paths('nnstreamer_sink', 'nnscustom_framecounter.c'),
   dependencies: [glib_dep, nnstreamer_dep],
   install: false
 )
 
+library('nnscustom_drop_buffer',
+  join_paths('nnstreamer_sink', 'nnscustom_drop_buffer.c'),
+  dependencies: [nnstreamer_dep],
+  install: false
+)
+
 # Build and copy exe for ssat
 libpng_dep = dependency('libpng', required: false)
 if libpng_dep.found()
diff --git a/tests/nnstreamer_sink/nnscustom_drop_buffer.c b/tests/nnstreamer_sink/nnscustom_drop_buffer.c
new file mode 100644 (file)
index 0000000..08d43bd
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * NNStreamer custom filter to test buffer-drop
+ * Copyright (C) 2018 Jaeyun Jung <jy1210.jung@samsung.com>
+ *
+ * LICENSE: LGPL-2.1
+ *
+ * @file  nnscustom_drop_buffer.c
+ * @date  25 Jan 2019
+ * @author  Jaeyun Jung <jy1210.jung@samsung.com>
+ * @brief  Custom filter to drop incoming buffer (skip 9 buffers, then pass 1 buffer)
+ * @bug  No known bugs
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <tensor_filter_custom.h>
+
+/**
+ * @brief nnstreamer custom filter private data
+ */
+typedef struct _pt_data
+{
+  unsigned int count; /**< This counts incoming buffer */
+} pt_data;
+
+/**
+ * @brief nnstreamer custom filter standard vmethod
+ * Refer tensor_filter_custom.h
+ */
+static void *
+pt_init (const GstTensorFilterProperties * prop)
+{
+  pt_data *data = (pt_data *) malloc (sizeof (pt_data));
+
+  assert (data);
+  data->count = 0;
+
+  return data;
+}
+
+/**
+ * @brief nnstreamer custom filter standard vmethod
+ * Refer tensor_filter_custom.h
+ */
+static void
+pt_exit (void *_data, const GstTensorFilterProperties * prop)
+{
+  pt_data *data = _data;
+
+  assert (data);
+  free (data);
+}
+
+/**
+ * @brief nnstreamer custom filter standard vmethod
+ * Refer tensor_filter_custom.h
+ */
+static int
+set_inputDim (void *_data, const GstTensorFilterProperties * prop,
+    const GstTensorsInfo * in_info, GstTensorsInfo * out_info)
+{
+  int i, t;
+
+  assert (in_info);
+  assert (out_info);
+
+  /** @todo use common function to copy tensor info */
+  out_info->num_tensors = in_info->num_tensors;
+
+  for (t = 0; t < in_info->num_tensors; t++) {
+    out_info->info[t].name = NULL;
+    out_info->info[t].type = in_info->info[t].type;
+
+    for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+      out_info->info[t].dimension[i] = in_info->info[t].dimension[i];
+    }
+  }
+
+  return 0;
+}
+
+/**
+ * @brief nnstreamer custom filter standard vmethod
+ * Refer tensor_filter_custom.h
+ */
+static int
+invoke (void *_data, const GstTensorFilterProperties * prop,
+    const GstTensorMemory * input, GstTensorMemory * output)
+{
+  pt_data *data = _data;
+  int t;
+
+  assert (data);
+
+  data->count++;
+  if (data->count % 10) {
+    /* drop this buffer */
+    /** @todo define enum to indicate status code */
+    return 2;
+  }
+
+  for (t = 0; t < prop->output_meta.num_tensors; t++) {
+    memcpy (output[t].data, input[t].data, input[t].size);
+  }
+
+  return 0;
+}
+
+static NNStreamer_custom_class NNStreamer_custom_body = {
+  .initfunc = pt_init,
+  .exitfunc = pt_exit,
+  .setInputDim = set_inputDim,
+  .invoke = invoke,
+};
+
+/* The dyn-loaded object */
+NNStreamer_custom_class *NNStreamer_custom = &NNStreamer_custom_body;
index 27221d3..6ef77fe 100644 (file)
@@ -89,6 +89,7 @@ typedef enum
   TEST_TYPE_TENSORS_MIX, /**< pipeline for tensors with tensor_mux, tensor_demux */
   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_CUSTOM_BUF_DROP, /**< pipeline to test buffer-drop in tensor_filter using custom filter */
   TEST_TYPE_NEGO_FAILED, /**< pipeline to test caps negotiation */
   TEST_TYPE_VIDEO_RGB_SPLIT, /**< pipeline to test tensor_split */
   TEST_TYPE_VIDEO_RGB_AGGR_1, /**< pipeline to test tensor_aggregator (change dimension index 3 : 1 > 10)*/
@@ -670,6 +671,14 @@ _setup_pipeline (TestOption & option)
           "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_CUSTOM_BUF_DROP:
+      /* audio stream to test buffer-drop using custom filter */
+      str_pipeline =
+          g_strdup_printf
+          ("audiotestsrc num-buffers=%d samplesperbuffer=200 ! audioconvert ! audio/x-raw,format=S16LE,rate=16000,channels=1 ! "
+          "tensor_converter frames-per-tensor=200 ! tensor_filter framework=custom model=./tests/libnnscustom_drop_buffer.so ! tensor_sink name=test_sink",
+          option.num_buffers);
+      break;
     case TEST_TYPE_NEGO_FAILED:
       /** caps negotiation failed */
       str_pipeline =
@@ -2705,6 +2714,48 @@ TEST (tensor_stream_test, custom_filter_tensors)
 }
 
 /**
+ * @brief Test to drop incoming buffer in tensor_filter using custom filter.
+ */
+TEST (tensor_stream_test, custom_filter_drop_buffer)
+{
+  const guint num_buffers = 22;
+  TestOption option = { num_buffers, TEST_TYPE_CUSTOM_BUF_DROP };
+
+  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, 2);
+  EXPECT_EQ (g_test_data.mem_blocks, 1);
+  EXPECT_EQ (g_test_data.received_size, 200 * 2);
+
+  /** check caps name */
+  EXPECT_TRUE (g_str_equal (g_test_data.caps_name, "other/tensor"));
+
+  /** check timestamp */
+  EXPECT_FALSE (g_test_data.invalid_timestamp);
+
+  /** check tensor config for audio */
+  EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.tensor_config));
+  EXPECT_EQ (g_test_data.tensor_config.info.type, _NNS_INT16);
+  EXPECT_EQ (g_test_data.tensor_config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.tensor_config.info.dimension[1], 200);
+  EXPECT_EQ (g_test_data.tensor_config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.tensor_config.info.dimension[3], 1);
+  EXPECT_EQ (g_test_data.tensor_config.rate_n, 16000);
+  EXPECT_EQ (g_test_data.tensor_config.rate_d, 1);
+
+  EXPECT_FALSE (g_test_data.test_failed);
+  _free_test_data ();
+}
+
+/**
  * @brief Test for tensors (mixed, video and audio).
  */
 TEST (tensor_stream_test, tensors_mix)