[Sink/Example] change sink caps / property
authorjy1210.jung <jy1210.jung@samsung.com>
Fri, 13 Jul 2018 07:49:41 +0000 (16:49 +0900)
committer함명주/동작제어Lab(SR)/Principal Engineer/삼성전자 <myungjoo.ham@samsung.com>
Mon, 16 Jul 2018 02:44:11 +0000 (11:44 +0900)
1. change sink pad caps (any > other/tensor)
2. change property type and name (signal-rate)
3. remove unnecessary functions and params
4. add testcase for caps nego failed

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

Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
gst/tensor_sink/tensor_sink.c
gst/tensor_sink/tensor_sink.h
nnstreamer_example/example_cam/nnstreamer_example_cam.c
nnstreamer_example/example_sink/nnstreamer_sink_example.c
nnstreamer_example/example_sink/nnstreamer_sink_example_play.c
tests/nnstreamer_sink/unittest_sink.cpp

index aad7c27..e96a0cc 100644 (file)
@@ -1,8 +1,8 @@
-/*
+/**
  * GStreamer
  * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
  * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) 2018 nnstreamer <nnstreamer sec>
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -13,7 +13,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Library General Public License for more details.
- *
  */
 
 /**
@@ -24,7 +23,7 @@
  * @file       tensor_sink.c
  * @date       15 June 2018
  * @brief      GStreamer plugin to handle tensor stream
- * @see                http://github.com/TO-BE-DETERMINED-SOON
+ * @see                http://github.com/nnsuite/nnstreamer
  * @see                https://github.sec.samsung.net/STAR/nnstreamer
  * @author     Jaeyun Jung <jy1210.jung@samsung.com>
  * @bug                No known bugs except for NYI items
@@ -50,7 +49,7 @@
 GST_DEBUG_CATEGORY_STATIC (gst_tensor_sink_debug);
 #define GST_CAT_DEFAULT gst_tensor_sink_debug
 
-/* signals and args */
+/** signals and args */
 enum
 {
   SIGNAL_NEW_DATA,
@@ -62,7 +61,7 @@ enum
 enum
 {
   PROP_0,
-  PROP_RENDER_RATE,
+  PROP_SIGNAL_RATE,
   PROP_EMIT_SIGNAL,
   PROP_SILENT
 };
@@ -73,9 +72,9 @@ enum
 #define DEFAULT_EMIT_SIGNAL TRUE
 
 /**
- * @brief Buffers rendered per second.
+ * @brief New data signals per second.
  */
-#define DEFAULT_RENDER_RATE 0
+#define DEFAULT_SIGNAL_RATE 0
 
 /**
  * @brief Flag to print minimized log.
@@ -110,14 +109,14 @@ enum
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
+    GST_STATIC_CAPS (GST_TENSOR_CAP_DEFAULT));
 
 /**
  * @brief Variable for signal ids.
  */
 static guint _tensor_sink_signals[LAST_SIGNAL] = { 0 };
 
-/* GObject method implementation */
+/** GObject method implementation */
 static void gst_tensor_sink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void gst_tensor_sink_get_property (GObject * object, guint prop_id,
@@ -125,7 +124,7 @@ static void gst_tensor_sink_get_property (GObject * object, guint prop_id,
 static void gst_tensor_sink_dispose (GObject * object);
 static void gst_tensor_sink_finalize (GObject * object);
 
-/* GstBaseSink method implementation */
+/** GstBaseSink method implementation */
 static gboolean gst_tensor_sink_start (GstBaseSink * sink);
 static gboolean gst_tensor_sink_stop (GstBaseSink * sink);
 static gboolean gst_tensor_sink_event (GstBaseSink * sink, GstEvent * event);
@@ -137,26 +136,24 @@ static GstFlowReturn gst_tensor_sink_render_list (GstBaseSink * sink,
 static gboolean gst_tensor_sink_set_caps (GstBaseSink * sink, GstCaps * caps);
 static GstCaps *gst_tensor_sink_get_caps (GstBaseSink * sink, GstCaps * filter);
 
-/* internal functions */
+/** internal functions */
 static void _tensor_sink_render_buffer (GstTensorSink * self,
     GstBuffer * buffer);
 static void _tensor_sink_set_last_render_time (GstTensorSink * self,
     GstClockTime now);
 static GstClockTime _tensor_sink_get_last_render_time (GstTensorSink * self);
-static void _tensor_sink_set_render_rate (GstTensorSink * self, guint64 rate);
-static guint64 _tensor_sink_get_render_rate (GstTensorSink * self);
+static void _tensor_sink_set_signal_rate (GstTensorSink * self, guint rate);
+static guint _tensor_sink_get_signal_rate (GstTensorSink * self);
 static void _tensor_sink_set_emit_signal (GstTensorSink * self, gboolean emit);
 static gboolean _tensor_sink_get_emit_signal (GstTensorSink * self);
 static void _tensor_sink_set_silent (GstTensorSink * self, gboolean silent);
 static gboolean _tensor_sink_get_silent (GstTensorSink * self);
 
-/* functions to initialize */
-static void _tensor_sink_do_init (GType type);
+/** functions to initialize */
 static gboolean _tensor_sink_plugin_init (GstPlugin * plugin);
 
 #define gst_tensor_sink_parent_class parent_class
-G_DEFINE_TYPE_WITH_CODE (GstTensorSink, gst_tensor_sink, GST_TYPE_BASE_SINK,
-    _tensor_sink_do_init (g_define_type_id));
+G_DEFINE_TYPE (GstTensorSink, gst_tensor_sink, GST_TYPE_BASE_SINK);
 
 /**
  * @brief Initialize tensor_sink class.
@@ -172,17 +169,17 @@ gst_tensor_sink_class_init (GstTensorSinkClass * klass)
   element_class = GST_ELEMENT_CLASS (klass);
   bsink_class = GST_BASE_SINK_CLASS (klass);
 
-  /* GObject methods */
+  /** GObject methods */
   gobject_class->set_property = gst_tensor_sink_set_property;
   gobject_class->get_property = gst_tensor_sink_get_property;
   gobject_class->dispose = gst_tensor_sink_dispose;
   gobject_class->finalize = gst_tensor_sink_finalize;
 
-  /* properties */
-  g_object_class_install_property (gobject_class, PROP_RENDER_RATE,
-      g_param_spec_uint64 ("render-rate", "Render rate",
-          "Buffers rendered per second (0 for unlimited, max 500)", 0, 500,
-          DEFAULT_RENDER_RATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /** properties */
+  g_object_class_install_property (gobject_class, PROP_SIGNAL_RATE,
+      g_param_spec_uint ("signal-rate", "Signal rate",
+          "New data signals per second (0 for unlimited, max 500)", 0, 500,
+          DEFAULT_SIGNAL_RATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (gobject_class, PROP_EMIT_SIGNAL,
       g_param_spec_boolean ("emit-signal", "Emit signal",
@@ -193,7 +190,7 @@ gst_tensor_sink_class_init (GstTensorSinkClass * klass)
       g_param_spec_boolean ("silent", "Silent", "Produce verbose output",
           DEFAULT_SILENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  /* signals */
+  /** signals */
   _tensor_sink_signals[SIGNAL_NEW_DATA] =
       g_signal_new ("new-data", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       G_STRUCT_OFFSET (GstTensorSinkClass, new_data), NULL, NULL, NULL,
@@ -212,11 +209,11 @@ gst_tensor_sink_class_init (GstTensorSinkClass * klass)
   gst_element_class_set_static_metadata (element_class,
       "Tensor_Sink",
       "Sink/Tensor",
-      "Sink element to handle tensor stream", "nnstreamer <nnstreamer sec>");
+      "Sink element to handle tensor stream", "Samsung Electronics Co., Ltd.");
 
   gst_element_class_add_static_pad_template (element_class, &sinktemplate);
 
-  /* GstBaseSink methods */
+  /** GstBaseSink methods */
   bsink_class->start = GST_DEBUG_FUNCPTR (gst_tensor_sink_start);
   bsink_class->stop = GST_DEBUG_FUNCPTR (gst_tensor_sink_stop);
   bsink_class->event = GST_DEBUG_FUNCPTR (gst_tensor_sink_event);
@@ -239,14 +236,14 @@ gst_tensor_sink_init (GstTensorSink * self)
 
   g_mutex_init (&self->mutex);
 
-  /* init properties */
+  /** init properties */
   self->silent = DEFAULT_SILENT;
   self->emit_signal = DEFAULT_EMIT_SIGNAL;
-  self->render_rate = DEFAULT_RENDER_RATE;
+  self->signal_rate = DEFAULT_SIGNAL_RATE;
   self->last_render_time = GST_CLOCK_TIME_NONE;
   self->in_caps = NULL;
 
-  /* enable qos event */
+  /** enable qos event */
   gst_base_sink_set_sync (bsink, DEFAULT_SYNC);
   gst_base_sink_set_max_lateness (bsink, DEFAULT_LATENESS);
   gst_base_sink_set_qos_enabled (bsink, DEFAULT_QOS);
@@ -266,8 +263,8 @@ gst_tensor_sink_set_property (GObject * object, guint prop_id,
   self = GST_TENSOR_SINK (object);
 
   switch (prop_id) {
-    case PROP_RENDER_RATE:
-      _tensor_sink_set_render_rate (self, g_value_get_uint64 (value));
+    case PROP_SIGNAL_RATE:
+      _tensor_sink_set_signal_rate (self, g_value_get_uint (value));
       break;
 
     case PROP_EMIT_SIGNAL:
@@ -298,8 +295,8 @@ gst_tensor_sink_get_property (GObject * object, guint prop_id,
   self = GST_TENSOR_SINK (object);
 
   switch (prop_id) {
-    case PROP_RENDER_RATE:
-      g_value_set_uint64 (value, _tensor_sink_get_render_rate (self));
+    case PROP_SIGNAL_RATE:
+      g_value_set_uint (value, _tensor_sink_get_signal_rate (self));
       break;
 
     case PROP_EMIT_SIGNAL:
@@ -360,7 +357,7 @@ gst_tensor_sink_finalize (GObject * object)
 static gboolean
 gst_tensor_sink_start (GstBaseSink * sink)
 {
-  /* load and init resources */
+  /** load and init resources */
   return TRUE;
 }
 
@@ -372,7 +369,7 @@ gst_tensor_sink_start (GstBaseSink * sink)
 static gboolean
 gst_tensor_sink_stop (GstBaseSink * sink)
 {
-  /* free resources */
+  /** free resources */
   return TRUE;
 }
 
@@ -431,7 +428,7 @@ gst_tensor_sink_query (GstBaseSink * sink, GstQuery * query)
   switch (type) {
     case GST_QUERY_SEEKING:
       DLOG ("query SEEKING");
-      /* tensor sink does not support seeking */
+      /** tensor sink does not support seeking */
       gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
       gst_query_set_seeking (query, format, FALSE, 0, -1);
       return TRUE;
@@ -556,14 +553,14 @@ static void
 _tensor_sink_render_buffer (GstTensorSink * self, GstBuffer * buffer)
 {
   GstClockTime now = GST_CLOCK_TIME_NONE;
-  guint64 render_rate;
+  guint signal_rate;
   gboolean notify = FALSE;
 
   g_return_if_fail (GST_IS_TENSOR_SINK (self));
 
-  render_rate = _tensor_sink_get_render_rate (self);
+  signal_rate = _tensor_sink_get_signal_rate (self);
 
-  if (render_rate) {
+  if (signal_rate) {
     GstClock *clock;
     GstClockTime render_time;
     GstClockTime last_render_time;
@@ -574,19 +571,19 @@ _tensor_sink_render_buffer (GstTensorSink * self, GstBuffer * buffer)
       now = gst_clock_get_time (clock);
       last_render_time = _tensor_sink_get_last_render_time (self);
 
-      /* time for next render */
-      render_time = (1000 / render_rate) * GST_MSECOND + last_render_time;
+      /** time for next signal */
+      render_time = (1000 / signal_rate) * GST_MSECOND + last_render_time;
 
       if (!GST_CLOCK_TIME_IS_VALID (last_render_time) ||
           GST_CLOCK_DIFF (now, render_time) <= 0) {
-        /* send data after render time, or firstly received buffer */
+        /** send data after render time, or firstly received buffer */
         notify = TRUE;
       }
 
       gst_object_unref (clock);
     }
   } else {
-    /* send data if render rate is 0 */
+    /** send data if signal rate is 0 */
     notify = TRUE;
   }
 
@@ -594,8 +591,8 @@ _tensor_sink_render_buffer (GstTensorSink * self, GstBuffer * buffer)
     _tensor_sink_set_last_render_time (self, now);
 
     if (_tensor_sink_get_emit_signal (self)) {
-      DLOG ("signal for new data [%" GST_TIME_FORMAT "], rate [%ld]",
-          GST_TIME_ARGS (now), render_rate);
+      DLOG ("signal for new data [%" GST_TIME_FORMAT "], rate [%d]",
+          GST_TIME_ARGS (now), signal_rate);
       g_signal_emit (self, _tensor_sink_signals[SIGNAL_NEW_DATA], 0, buffer);
     }
   }
@@ -632,31 +629,31 @@ _tensor_sink_get_last_render_time (GstTensorSink * self)
 }
 
 /**
- * @brief Setter for value render_rate.
+ * @brief Setter for value signal_rate.
  */
 static void
-_tensor_sink_set_render_rate (GstTensorSink * self, guint64 rate)
+_tensor_sink_set_signal_rate (GstTensorSink * self, guint rate)
 {
   g_return_if_fail (GST_IS_TENSOR_SINK (self));
 
-  DLOG ("set render_rate to %ld", rate);
+  DLOG ("set signal_rate to %d", rate);
   g_mutex_lock (&self->mutex);
-  self->render_rate = rate;
+  self->signal_rate = rate;
   g_mutex_unlock (&self->mutex);
 }
 
 /**
- * @brief Getter for value render_rate.
+ * @brief Getter for value signal_rate.
  */
-static guint64
-_tensor_sink_get_render_rate (GstTensorSink * self)
+static guint
+_tensor_sink_get_signal_rate (GstTensorSink * self)
 {
-  guint64 rate;
+  guint rate;
 
   g_return_val_if_fail (GST_IS_TENSOR_SINK (self), 0);
 
   g_mutex_lock (&self->mutex);
-  rate = self->render_rate;
+  rate = self->signal_rate;
   g_mutex_unlock (&self->mutex);
 
   return rate;
@@ -717,15 +714,6 @@ _tensor_sink_get_silent (GstTensorSink * self)
 }
 
 /**
- * @brief Function used in type implementation.
- */
-static void
-_tensor_sink_do_init (GType type)
-{
-  /* add interface */
-}
-
-/**
  * @brief Function to initialize the plugin.
  *
  * See GstPluginInitFunc() for more details.
index 80cd2df..5b0551a 100644 (file)
@@ -2,7 +2,7 @@
  * GStreamer
  * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
  * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
- * Copyright (C) 2018 nnstreamer <nnstreamer sec>
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Library General Public License for more details.
- *
  */
+
 /**
  * @file       tensor_sink.h
  * @date       15 June 2018
  * @brief      GStreamer plugin to handle tensor stream
- * @see                http://github.com/TO-BE-DETERMINED-SOON
+ * @see                http://github.com/nnsuite/nnstreamer
  * @see                https://github.sec.samsung.net/STAR/nnstreamer
  * @author     Jaeyun Jung <jy1210.jung@samsung.com>
  * @bug                No known bugs except for NYI items
@@ -60,7 +60,7 @@ struct _GstTensorSink
   GMutex mutex; /**< mutex for processing */
   gboolean silent; /**< true to print minimized log */
   gboolean emit_signal; /**< true to emit signal for new data, eos */
-  guint64 render_rate; /**< buffers rendered per second */
+  guint signal_rate; /**< new data signals per second */
   GstClockTime last_render_time; /**< buffer rendered time */
   GstCaps *in_caps; /**< received caps */
 };
@@ -74,7 +74,7 @@ struct _GstTensorSinkClass
 {
   GstBaseSinkClass parent_class; /**< parent class */
 
-  /* signals */
+  /** signals */
   void (*new_data) (GstElement * element, GstBuffer * buffer); /**< signal when new data received */
   void (*stream_start) (GstElement * element); /**< signal when stream started */
   void (*eos) (GstElement * element); /**< signal when end of stream reached */
@@ -87,4 +87,4 @@ GType gst_tensor_sink_get_type (void);
 
 G_END_DECLS
 
-#endif /* __GST_TENSOR_SINK_H__ */
+#endif /** __GST_TENSOR_SINK_H__ */
index d499fbe..a570786 100644 (file)
@@ -85,6 +85,8 @@ _parse_err_message (GstMessage * message)
   gchar *debug;
   GError *error;
 
+  g_return_if_fail (message != NULL);
+
   switch (GST_MESSAGE_TYPE (message)) {
     case GST_MESSAGE_ERROR:
       gst_message_parse_error (message, &error, &debug);
@@ -188,17 +190,17 @@ main (int argc, char **argv)
 
   _print_log ("start app..");
 
-  /* check cam */
+  /** check cam */
   _check_cond_err (_check_cam_device (cam_dev));
 
-  /* init gstreamer */
+  /** init gstreamer */
   gst_init (&argc, &argv);
 
-  /* main loop */
+  /** main loop */
   g_app.loop = g_main_loop_new (NULL, FALSE);
   _check_cond_err (g_app.loop != NULL);
 
-  /* init data pipeline */
+  /** init data pipeline */
   str_pipeline =
       g_strdup_printf
       ("v4l2src name=cam_src ! "
@@ -215,7 +217,7 @@ main (int argc, char **argv)
   g_free (str_pipeline);
   _check_cond_err (g_app.pipeline != NULL);
 
-  /* data message callback */
+  /** data message callback */
   g_app.bus = gst_element_get_bus (g_app.pipeline);
   _check_cond_err (g_app.bus != NULL);
 
@@ -224,10 +226,10 @@ main (int argc, char **argv)
       (GCallback) _message_cb, NULL);
   _check_cond_err (handle_id > 0);
 
-  /* start pipeline */
+  /** start pipeline */
   gst_element_set_state (g_app.pipeline, GST_STATE_PLAYING);
 
-  /* set window title */
+  /** set window title */
   element = gst_bin_get_by_name (GST_BIN (g_app.pipeline), "img_mixed");
   _set_window_title (element, "Mixed");
   gst_object_unref (element);
@@ -236,13 +238,13 @@ main (int argc, char **argv)
   _set_window_title (element, "Original");
   gst_object_unref (element);
 
-  /* run main loop */
+  /** run main loop */
   g_main_loop_run (g_app.loop);
+  /** quit when received eos or error message */
 
-  /* cam source element */
+  /** cam source element */
   element = gst_bin_get_by_name (GST_BIN (g_app.pipeline), "cam_src");
 
-  /* quit when received eos or error message */
   gst_element_set_state (element, GST_STATE_READY);
   gst_element_set_state (g_app.pipeline, GST_STATE_READY);
 
index cdb41ff..e7ef6ac 100644 (file)
@@ -43,7 +43,6 @@ typedef struct
   GMainLoop *loop; /**< main event loop */
   GstElement *pipeline; /**< gst pipeline for test */
   GstBus *bus; /**< gst bus for test */
-  GstElement *sink; /**< tensor sink element */
 
   guint received; /**< received buffer count */
 } AppData;
@@ -51,7 +50,7 @@ typedef struct
 /**
  * @brief Data for pipeline and result.
  */
-static AppData g_app_data;
+static AppData g_app;
 
 /**
  * @brief Free resources in app data.
@@ -59,25 +58,20 @@ static AppData g_app_data;
 static void
 _free_app_data (void)
 {
-  if (g_app_data.loop) {
-    g_main_loop_unref (g_app_data.loop);
-    g_app_data.loop = NULL;
+  if (g_app.loop) {
+    g_main_loop_unref (g_app.loop);
+    g_app.loop = NULL;
   }
 
-  if (g_app_data.bus) {
-    gst_bus_remove_signal_watch (g_app_data.bus);
-    gst_object_unref (g_app_data.bus);
-    g_app_data.bus = NULL;
+  if (g_app.bus) {
+    gst_bus_remove_signal_watch (g_app.bus);
+    gst_object_unref (g_app.bus);
+    g_app.bus = NULL;
   }
 
-  if (g_app_data.sink) {
-    gst_object_unref (g_app_data.sink);
-    g_app_data.sink = NULL;
-  }
-
-  if (g_app_data.pipeline) {
-    gst_object_unref (g_app_data.pipeline);
-    g_app_data.pipeline = NULL;
+  if (g_app.pipeline) {
+    gst_object_unref (g_app.pipeline);
+    g_app.pipeline = NULL;
   }
 }
 
@@ -90,6 +84,8 @@ _parse_err_message (GstMessage * message)
   gchar *debug;
   GError *error;
 
+  g_return_if_fail (message != NULL);
+
   switch (GST_MESSAGE_TYPE (message)) {
     case GST_MESSAGE_ERROR:
       gst_message_parse_error (message, &error, &debug);
@@ -109,6 +105,27 @@ _parse_err_message (GstMessage * message)
 }
 
 /**
+ * @brief Function to print caps.
+ */
+static void
+_parse_caps (GstCaps * caps)
+{
+  guint caps_size, i;
+
+  g_return_if_fail (caps != NULL);
+
+  caps_size = gst_caps_get_size (caps);
+
+  for (i = 0; i < caps_size; i++) {
+    GstStructure *structure = gst_caps_get_structure (caps, i);
+    gchar *str = gst_structure_to_string (structure);
+
+    _print_log ("[%d] %s", i, str);
+    g_free (str);
+  }
+}
+
+/**
  * @brief Callback for message.
  */
 static void
@@ -117,13 +134,13 @@ _message_cb (GstBus * bus, GstMessage * message, gpointer user_data)
   switch (GST_MESSAGE_TYPE (message)) {
     case GST_MESSAGE_EOS:
       _print_log ("received eos message");
-      g_main_loop_quit (g_app_data.loop);
+      g_main_loop_quit (g_app.loop);
       break;
 
     case GST_MESSAGE_ERROR:
       _print_log ("received error message");
       _parse_err_message (message);
-      g_main_loop_quit (g_app_data.loop);
+      g_main_loop_quit (g_app.loop);
       break;
 
     case GST_MESSAGE_WARNING:
@@ -146,11 +163,13 @@ _message_cb (GstBus * bus, GstMessage * message, gpointer user_data)
 static void
 _new_data_cb (GstElement * element, GstBuffer * buffer, gpointer user_data)
 {
-  g_app_data.received++;
-  _print_log ("new data callback [%d]", g_app_data.received);
+  g_app.received++;
+  if (g_app.received % 150 == 0) {
+    _print_log ("receiving new data [%d]", g_app.received);
+  }
 
-  /* example to get data */
-  if (DBG) {
+  /** example to get data */
+  {
     GstMemory *mem;
     GstMapInfo info;
     guint i;
@@ -161,7 +180,7 @@ _new_data_cb (GstElement * element, GstBuffer * buffer, gpointer user_data)
       mem = gst_buffer_peek_memory (buffer, i);
 
       if (gst_memory_map (mem, &info, GST_MAP_READ)) {
-        /* check data (info.data, info.size) */
+        /** check data (info.data, info.size) */
         _print_log ("received %zd", info.size);
 
         gst_memory_unmap (mem, &info);
@@ -169,30 +188,27 @@ _new_data_cb (GstElement * element, GstBuffer * buffer, gpointer user_data)
     }
   }
 
-  /* example to get negotiated caps */
-  if (DBG) {
+  /** example to get caps */
+  {
     GstPad *sink_pad;
     GstCaps *caps;
 
-    sink_pad = gst_element_get_static_pad (g_app_data.sink, "sink");
+    sink_pad = gst_element_get_static_pad (element, "sink");
 
     if (sink_pad) {
+      /** negotiated */
       caps = gst_pad_get_current_caps (sink_pad);
 
       if (caps) {
-        guint caps_size, i;
-
-        caps_size = gst_caps_get_size (caps);
-        _print_log ("caps size is %d", caps_size);
-
-        for (i = 0; i < caps_size; i++) {
-          GstStructure *structure = gst_caps_get_structure (caps, i);
-          gchar *str = gst_structure_to_string (structure);
+        _parse_caps (caps);
+        gst_caps_unref (caps);
+      }
 
-          _print_log ("[%d] %s", i, str);
-          g_free (str);
-        }
+      /** template */
+      caps = gst_pad_get_pad_template_caps (sink_pad);
 
+      if (caps) {
+        _parse_caps (caps);
         gst_caps_unref (caps);
       }
 
@@ -232,75 +248,77 @@ main (int argc, char **argv)
   gchar *str_pipeline;
   gulong handle_id;
   GstStateChangeReturn state_ret;
+  GstElement *element;
 
-  /* init gstreamer */
+  /** init gstreamer */
   gst_init (&argc, &argv);
 
-  /* init app variable */
-  g_app_data.received = 0;
+  /** init app variable */
+  g_app.received = 0;
 
-  /* main loop and pipeline */
-  g_app_data.loop = g_main_loop_new (NULL, FALSE);
-  _check_cond_err (g_app_data.loop != NULL);
+  /** main loop and pipeline */
+  g_app.loop = g_main_loop_new (NULL, FALSE);
+  _check_cond_err (g_app.loop != NULL);
 
-  /* 640x480 30fps for test */
+  /** 640x480 30fps for test */
   str_pipeline =
       g_strdup_printf
       ("videotestsrc num-buffers=%d ! video/x-raw,format=RGB,width=%d,height=%d ! "
       "tensor_converter ! tensor_sink name=tensor_sink",
       num_buffers, width, height);
-  g_app_data.pipeline = gst_parse_launch (str_pipeline, NULL);
+  g_app.pipeline = gst_parse_launch (str_pipeline, NULL);
   g_free (str_pipeline);
-  _check_cond_err (g_app_data.pipeline != NULL);
+  _check_cond_err (g_app.pipeline != NULL);
 
-  /* message callback */
-  g_app_data.bus = gst_element_get_bus (g_app_data.pipeline);
-  _check_cond_err (g_app_data.bus != NULL);
+  /** message callback */
+  g_app.bus = gst_element_get_bus (g_app.pipeline);
+  _check_cond_err (g_app.bus != NULL);
 
-  gst_bus_add_signal_watch (g_app_data.bus);
-  handle_id = g_signal_connect (g_app_data.bus, "message",
+  gst_bus_add_signal_watch (g_app.bus);
+  handle_id = g_signal_connect (g_app.bus, "message",
       (GCallback) _message_cb, NULL);
   _check_cond_err (handle_id > 0);
 
-  /* get tensor sink element using name */
-  g_app_data.sink =
-      gst_bin_get_by_name (GST_BIN (g_app_data.pipeline), "tensor_sink");
-  _check_cond_err (g_app_data.sink != NULL);
+  /** get tensor sink element using name */
+  element = gst_bin_get_by_name (GST_BIN (g_app.pipeline), "tensor_sink");
+  _check_cond_err (element != NULL);
 
   if (DBG) {
-    /* print logs, default TRUE */
-    g_object_set (g_app_data.sink, "silent", (gboolean) FALSE, NULL);
+    /** print logs, default TRUE */
+    g_object_set (element, "silent", (gboolean) FALSE, NULL);
   }
 
-  /* enable emit-signal, default TRUE */
-  g_object_set (g_app_data.sink, "emit-signal", (gboolean) TRUE, NULL);
+  /** enable emit-signal, default TRUE */
+  g_object_set (element, "emit-signal", (gboolean) TRUE, NULL);
 
-  /* tensor sink signal : new data callback */
-  handle_id = g_signal_connect (g_app_data.sink, "new-data",
+  /** tensor sink signal : new data callback */
+  handle_id = g_signal_connect (element, "new-data",
       (GCallback) _new_data_cb, NULL);
   _check_cond_err (handle_id > 0);
 
-  /* tensor sink signal : stream-start callback, optional */
-  handle_id = g_signal_connect (g_app_data.sink, "stream-start",
+  /** tensor sink signal : stream-start callback, optional */
+  handle_id = g_signal_connect (element, "stream-start",
       (GCallback) _stream_start_cb, NULL);
   _check_cond_err (handle_id > 0);
 
-  /* tensor sink signal : eos callback, optional */
-  handle_id = g_signal_connect (g_app_data.sink, "eos",
-      (GCallback) _eos_cb, NULL);
+  /** tensor sink signal : eos callback, optional */
+  handle_id = g_signal_connect (element, "eos", (GCallback) _eos_cb, NULL);
   _check_cond_err (handle_id > 0);
 
-  /* start pipeline */
-  state_ret = gst_element_set_state (g_app_data.pipeline, GST_STATE_PLAYING);
+  gst_object_unref (element);
+
+  /** start pipeline */
+  state_ret = gst_element_set_state (g_app.pipeline, GST_STATE_PLAYING);
   _check_cond_err (state_ret != GST_STATE_CHANGE_FAILURE);
 
-  g_main_loop_run (g_app_data.loop);
+  /** run main loop */
+  g_main_loop_run (g_app.loop);
+  /** quit when received eos message */
 
-  /* quit when received eos message */
-  state_ret = gst_element_set_state (g_app_data.pipeline, GST_STATE_NULL);
+  state_ret = gst_element_set_state (g_app.pipeline, GST_STATE_NULL);
   _check_cond_err (state_ret != GST_STATE_CHANGE_FAILURE);
 
-  _print_log ("total received %d", g_app_data.received);
+  _print_log ("total received %d", g_app.received);
 
 error:
   _free_app_data ();
index 3d11506..3aec001 100644 (file)
@@ -50,17 +50,15 @@ typedef struct
   GstBus *data_bus; /**< gst bus for data pipeline */
   GstElement *player_pipeline; /**< gst pipeline for player */
   GstBus *player_bus; /**< gst bus for player pipeline */
-  GstElement *tensor_sink; /**< tensor sink element */
-  GstElement *player_src; /**< player source element */
 
-  guint received; /**< received buffer count */
   gboolean set_caps; /**< caps passed to player pipeline */
+  guint received; /**< received buffer count */
 } AppData;
 
 /**
  * @brief Data for pipeline and result.
  */
-static AppData g_app_data;
+static AppData g_app;
 
 /**
  * @brief Free resources in app data.
@@ -68,41 +66,31 @@ static AppData g_app_data;
 static void
 _free_app_data (void)
 {
-  if (g_app_data.loop) {
-    g_main_loop_unref (g_app_data.loop);
-    g_app_data.loop = NULL;
-  }
-
-  if (g_app_data.data_bus) {
-    gst_bus_remove_signal_watch (g_app_data.data_bus);
-    gst_object_unref (g_app_data.data_bus);
-    g_app_data.data_bus = NULL;
+  if (g_app.loop) {
+    g_main_loop_unref (g_app.loop);
+    g_app.loop = NULL;
   }
 
-  if (g_app_data.player_bus) {
-    gst_bus_remove_signal_watch (g_app_data.player_bus);
-    gst_object_unref (g_app_data.player_bus);
-    g_app_data.player_bus = NULL;
+  if (g_app.data_bus) {
+    gst_bus_remove_signal_watch (g_app.data_bus);
+    gst_object_unref (g_app.data_bus);
+    g_app.data_bus = NULL;
   }
 
-  if (g_app_data.tensor_sink) {
-    gst_object_unref (g_app_data.tensor_sink);
-    g_app_data.tensor_sink = NULL;
+  if (g_app.player_bus) {
+    gst_bus_remove_signal_watch (g_app.player_bus);
+    gst_object_unref (g_app.player_bus);
+    g_app.player_bus = NULL;
   }
 
-  if (g_app_data.player_src) {
-    gst_object_unref (g_app_data.player_src);
-    g_app_data.player_src = NULL;
+  if (g_app.data_pipeline) {
+    gst_object_unref (g_app.data_pipeline);
+    g_app.data_pipeline = NULL;
   }
 
-  if (g_app_data.data_pipeline) {
-    gst_object_unref (g_app_data.data_pipeline);
-    g_app_data.data_pipeline = NULL;
-  }
-
-  if (g_app_data.player_pipeline) {
-    gst_object_unref (g_app_data.player_pipeline);
-    g_app_data.player_pipeline = NULL;
+  if (g_app.player_pipeline) {
+    gst_object_unref (g_app.player_pipeline);
+    g_app.player_pipeline = NULL;
   }
 }
 
@@ -115,6 +103,8 @@ _parse_err_message (GstMessage * message)
   gchar *debug;
   GError *error;
 
+  g_return_if_fail (message != NULL);
+
   switch (GST_MESSAGE_TYPE (message)) {
     case GST_MESSAGE_ERROR:
       gst_message_parse_error (message, &error, &debug);
@@ -139,16 +129,21 @@ _parse_err_message (GstMessage * message)
 static void
 _data_message_cb (GstBus * bus, GstMessage * message, gpointer user_data)
 {
+  GstElement *player_src;
+
   switch (GST_MESSAGE_TYPE (message)) {
     case GST_MESSAGE_EOS:
       _print_log ("[data] received eos message");
-      gst_app_src_end_of_stream (GST_APP_SRC (g_app_data.player_src));
+      player_src = gst_bin_get_by_name (GST_BIN (g_app.player_pipeline),
+          "player_src");
+      gst_app_src_end_of_stream (GST_APP_SRC (player_src));
+      gst_object_unref (player_src);
       break;
 
     case GST_MESSAGE_ERROR:
       _print_log ("[data] received error message");
       _parse_err_message (message);
-      g_main_loop_quit (g_app_data.loop);
+      g_main_loop_quit (g_app.loop);
       break;
 
     case GST_MESSAGE_WARNING:
@@ -174,13 +169,13 @@ _player_message_cb (GstBus * bus, GstMessage * message, gpointer user_data)
   switch (GST_MESSAGE_TYPE (message)) {
     case GST_MESSAGE_EOS:
       _print_log ("[player] received eos message");
-      g_main_loop_quit (g_app_data.loop);
+      g_main_loop_quit (g_app.loop);
       break;
 
     case GST_MESSAGE_ERROR:
       _print_log ("[player] received error message");
       _parse_err_message (message);
-      g_main_loop_quit (g_app_data.loop);
+      g_main_loop_quit (g_app.loop);
       break;
 
     case GST_MESSAGE_WARNING:
@@ -203,31 +198,38 @@ _player_message_cb (GstBus * bus, GstMessage * message, gpointer user_data)
 static void
 _new_data_cb (GstElement * element, GstBuffer * buffer, gpointer user_data)
 {
-  g_app_data.received++;
-  _print_log ("new data callback [%d]", g_app_data.received);
+  GstElement *player_src;
+
+  g_app.received++;
+  if (g_app.received % 150 == 0) {
+    _print_log ("receiving new data [%d]", g_app.received);
+  }
 
-  if (!g_app_data.set_caps) {
+  player_src =
+      gst_bin_get_by_name (GST_BIN (g_app.player_pipeline), "player_src");
+
+  if (!g_app.set_caps) {
     GstPad *sink_pad;
     GstCaps *caps;
 
-    sink_pad = gst_element_get_static_pad (g_app_data.tensor_sink, "sink");
+    sink_pad = gst_element_get_static_pad (element, "sink");
 
     if (sink_pad) {
       caps = gst_pad_get_current_caps (sink_pad);
 
       if (caps) {
-        gst_app_src_set_caps (GST_APP_SRC (g_app_data.player_src), caps);
+        gst_app_src_set_caps (GST_APP_SRC (player_src), caps);
 
         gst_caps_unref (caps);
-        g_app_data.set_caps = TRUE;
+        g_app.set_caps = TRUE;
       }
 
       gst_object_unref (sink_pad);
     }
   }
 
-  gst_app_src_push_buffer (GST_APP_SRC (g_app_data.player_src),
-      gst_buffer_copy (buffer));
+  gst_app_src_push_buffer (GST_APP_SRC (player_src), gst_buffer_copy (buffer));
+  gst_object_unref (player_src);
 }
 
 /**
@@ -241,84 +243,82 @@ main (int argc, char **argv)
 
   gchar *str_pipeline;
   gulong handle_id;
+  GstElement *element;
 
-  /* init gstreamer */
+  /** init gstreamer */
   gst_init (&argc, &argv);
 
-  /* init app variable */
-  g_app_data.received = 0;
-  g_app_data.set_caps = FALSE;
+  /** init app variable */
+  g_app.set_caps = FALSE;
+  g_app.received = 0;
 
-  /* main loop and pipeline */
-  g_app_data.loop = g_main_loop_new (NULL, FALSE);
-  _check_cond_err (g_app_data.loop != NULL);
+  /** main loop and pipeline */
+  g_app.loop = g_main_loop_new (NULL, FALSE);
+  _check_cond_err (g_app.loop != NULL);
 
   str_pipeline =
       g_strdup_printf
       ("videotestsrc is-live=TRUE ! video/x-raw,format=RGB,width=%d,height=%d ! "
       "tensor_converter ! tensor_sink name=tensor_sink", width, height);
-  g_app_data.data_pipeline = gst_parse_launch (str_pipeline, NULL);
+  g_app.data_pipeline = gst_parse_launch (str_pipeline, NULL);
   g_free (str_pipeline);
-  _check_cond_err (g_app_data.data_pipeline != NULL);
+  _check_cond_err (g_app.data_pipeline != NULL);
 
-  /* data message callback */
-  g_app_data.data_bus = gst_element_get_bus (g_app_data.data_pipeline);
-  _check_cond_err (g_app_data.data_bus != NULL);
+  /** data message callback */
+  g_app.data_bus = gst_element_get_bus (g_app.data_pipeline);
+  _check_cond_err (g_app.data_bus != NULL);
 
-  gst_bus_add_signal_watch (g_app_data.data_bus);
-  handle_id = g_signal_connect (g_app_data.data_bus, "message",
+  gst_bus_add_signal_watch (g_app.data_bus);
+  handle_id = g_signal_connect (g_app.data_bus, "message",
       (GCallback) _data_message_cb, NULL);
   _check_cond_err (handle_id > 0);
 
-  /* get tensor sink element using name */
-  g_app_data.tensor_sink =
-      gst_bin_get_by_name (GST_BIN (g_app_data.data_pipeline), "tensor_sink");
-  _check_cond_err (g_app_data.tensor_sink != NULL);
+  /** get tensor sink element using name */
+  element = gst_bin_get_by_name (GST_BIN (g_app.data_pipeline), "tensor_sink");
+  _check_cond_err (element != NULL);
 
   if (DBG) {
-    /* print logs, default TRUE */
-    g_object_set (g_app_data.tensor_sink, "silent", (gboolean) FALSE, NULL);
+    /** print logs, default TRUE */
+    g_object_set (element, "silent", (gboolean) FALSE, NULL);
   }
 
-  /* enable emit-signal, default TRUE */
-  g_object_set (g_app_data.tensor_sink, "emit-signal", (gboolean) TRUE, NULL);
+  /** enable emit-signal, default TRUE */
+  g_object_set (element, "emit-signal", (gboolean) TRUE, NULL);
 
-  /* tensor sink signal : new data callback */
-  handle_id = g_signal_connect (g_app_data.tensor_sink, "new-data",
+  /** tensor sink signal : new data callback */
+  handle_id = g_signal_connect (element, "new-data",
       (GCallback) _new_data_cb, NULL);
   _check_cond_err (handle_id > 0);
 
-  /* init player pipeline */
+  gst_object_unref (element);
+
+  /** init player pipeline */
   str_pipeline =
       g_strdup_printf
       ("appsrc name=player_src ! tensordec ! videoconvert ! xvimagesink");
-  g_app_data.player_pipeline = gst_parse_launch (str_pipeline, NULL);
+  g_app.player_pipeline = gst_parse_launch (str_pipeline, NULL);
   g_free (str_pipeline);
-  _check_cond_err (g_app_data.player_pipeline != NULL);
+  _check_cond_err (g_app.player_pipeline != NULL);
 
-  /* player message callback */
-  g_app_data.player_bus = gst_element_get_bus (g_app_data.player_pipeline);
-  _check_cond_err (g_app_data.player_bus != NULL);
+  /** player message callback */
+  g_app.player_bus = gst_element_get_bus (g_app.player_pipeline);
+  _check_cond_err (g_app.player_bus != NULL);
 
-  gst_bus_add_signal_watch (g_app_data.player_bus);
-  handle_id = g_signal_connect (g_app_data.player_bus, "message",
+  gst_bus_add_signal_watch (g_app.player_bus);
+  handle_id = g_signal_connect (g_app.player_bus, "message",
       (GCallback) _player_message_cb, NULL);
   _check_cond_err (handle_id > 0);
 
-  /* player source element */
-  g_app_data.player_src =
-      gst_bin_get_by_name (GST_BIN (g_app_data.player_pipeline), "player_src");
-  _check_cond_err (g_app_data.player_src != NULL);
-
-  /* start pipeline */
-  gst_element_set_state (g_app_data.data_pipeline, GST_STATE_PLAYING);
-  gst_element_set_state (g_app_data.player_pipeline, GST_STATE_PLAYING);
+  /** start pipeline */
+  gst_element_set_state (g_app.data_pipeline, GST_STATE_PLAYING);
+  gst_element_set_state (g_app.player_pipeline, GST_STATE_PLAYING);
 
-  g_main_loop_run (g_app_data.loop);
+  /** run main loop */
+  g_main_loop_run (g_app.loop);
+  /** quit when received eos message */
 
-  /* quit when received eos message */
-  gst_element_set_state (g_app_data.data_pipeline, GST_STATE_NULL);
-  gst_element_set_state (g_app_data.player_pipeline, GST_STATE_NULL);
+  gst_element_set_state (g_app.data_pipeline, GST_STATE_NULL);
+  gst_element_set_state (g_app.player_pipeline, GST_STATE_NULL);
 
 error:
   _free_app_data ();
index 206d4f6..6e16fef 100644 (file)
@@ -5,6 +5,7 @@
  * @see                http://github.com/TO-BE-DETERMINED-SOON
  * @see                https://github.sec.samsung.net/STAR/nnstreamer
  * @author     Jaeyun Jung <jy1210.jung@samsung.com>
+ * @bug                No known bugs.
  */
 
 #include <gtest/gtest.h>
@@ -127,57 +128,6 @@ _new_data_cb (GstElement * element, GstBuffer * buffer, gpointer user_data)
 {
   g_test_data.received++;
   _print_log ("new data callback [%d]", g_test_data.received);
-
-  /* example to get data */
-  if (DBG) {
-    GstMemory *mem;
-    GstMapInfo info;
-    guint i;
-    guint num_mems;
-
-    num_mems = gst_buffer_n_memory (buffer);
-    for (i = 0; i < num_mems; i++) {
-      mem = gst_buffer_peek_memory (buffer, i);
-
-      if (gst_memory_map (mem, &info, GST_MAP_READ)) {
-        /* check data (info.data, info.size) */
-        _print_log ("received %zd", info.size);
-
-        gst_memory_unmap (mem, &info);
-      }
-    }
-  }
-
-  /* example to get negotiated caps */
-  if (DBG) {
-    GstPad *sink_pad;
-    GstCaps *caps;
-
-    sink_pad = gst_element_get_static_pad (g_test_data.sink, "sink");
-
-    if (sink_pad) {
-      g_object_get (sink_pad, "caps", &caps, NULL);
-
-      if (caps) {
-        guint caps_size, i;
-
-        caps_size = gst_caps_get_size (caps);
-        _print_log ("caps size is %d", caps_size);
-
-        for (i = 0; i < caps_size; i++) {
-          GstStructure *structure = gst_caps_get_structure (caps, i);
-          gchar *str = gst_structure_to_string (structure);
-
-          _print_log ("[%d] %s", i, str);
-          g_free (str);
-        }
-
-        gst_caps_unref (caps);
-      }
-
-      gst_object_unref (sink_pad);
-    }
-  }
 }
 
 /**
@@ -219,8 +169,8 @@ _setup_pipeline (const guint num_buffers)
 
   str_pipeline =
       g_strdup_printf
-      ("videotestsrc num-buffers=%d ! video/x-raw,width=640,height=480,framerate=(fraction)30/1 ! videoconvert ! video/x-raw,format=RGB ! tensor_converter ! tensor_sink name=test_sink",
-      num_buffers);
+      ("videotestsrc num-buffers=%d ! video/x-raw,width=160,height=120,format=RGB,framerate=(fraction)30/1 ! "
+      "tensor_converter ! tensor_sink name=test_sink", num_buffers);
   g_test_data.pipeline = gst_parse_launch (str_pipeline, NULL);
   g_free (str_pipeline);
   _check_cond_err (g_test_data.pipeline != NULL);
@@ -250,7 +200,7 @@ error:
  */
 TEST (tensor_sink_test, properties)
 {
-  guint64 rate, res_rate;
+  guint rate, res_rate;
   gint64 lateness, res_lateness;
   gboolean silent, res_silent;
   gboolean emit, res_emit;
@@ -259,15 +209,15 @@ TEST (tensor_sink_test, properties)
 
   ASSERT_TRUE (_setup_pipeline (1));
 
-  /* default render-rate is 0 */
-  g_object_get (g_test_data.sink, "render-rate", &rate, NULL);
+  /** default signal-rate is 0 */
+  g_object_get (g_test_data.sink, "signal-rate", &rate, NULL);
   EXPECT_EQ (rate, 0);
 
-  g_object_set (g_test_data.sink, "render-rate", (rate + 10), NULL);
-  g_object_get (g_test_data.sink, "render-rate", &res_rate, NULL);
+  g_object_set (g_test_data.sink, "signal-rate", (rate + 10), NULL);
+  g_object_get (g_test_data.sink, "signal-rate", &res_rate, NULL);
   EXPECT_EQ (res_rate, (rate + 10));
 
-  /* default emit-signal is TRUE */
+  /** default emit-signal is TRUE */
   g_object_get (g_test_data.sink, "emit-signal", &emit, NULL);
   EXPECT_EQ (emit, TRUE);
 
@@ -275,7 +225,7 @@ TEST (tensor_sink_test, properties)
   g_object_get (g_test_data.sink, "emit-signal", &res_emit, NULL);
   EXPECT_EQ (res_emit, !emit);
 
-  /* default silent is TRUE */
+  /** default silent is TRUE */
   g_object_get (g_test_data.sink, "silent", &silent, NULL);
   EXPECT_EQ (silent, TRUE);
 
@@ -283,7 +233,7 @@ TEST (tensor_sink_test, properties)
   g_object_get (g_test_data.sink, "silent", &res_silent, NULL);
   EXPECT_EQ (res_silent, !silent);
 
-  /* GstBaseSink:sync TRUE */
+  /** GstBaseSink:sync TRUE */
   g_object_get (g_test_data.sink, "sync", &sync, NULL);
   EXPECT_EQ (sync, TRUE);
 
@@ -291,16 +241,16 @@ TEST (tensor_sink_test, properties)
   g_object_get (g_test_data.sink, "sync", &res_sync, NULL);
   EXPECT_EQ (res_sync, !sync);
 
-  /* GstBaseSink:max-lateness 30ms */
+  /** GstBaseSink:max-lateness 30ms */
   g_object_get (g_test_data.sink, "max-lateness", &lateness, NULL);
   EXPECT_EQ (lateness, (30 * GST_MSECOND));
 
-  /* -1 means unlimited time */
+  /** -1 means unlimited time */
   g_object_set (g_test_data.sink, "max-lateness", (gint64) (-1), NULL);
   g_object_get (g_test_data.sink, "max-lateness", &res_lateness, NULL);
   EXPECT_EQ (res_lateness, -1);
 
-  /* GstBaseSink:qos TRUE */
+  /** GstBaseSink:qos TRUE */
   g_object_get (g_test_data.sink, "qos", &qos, NULL);
   EXPECT_EQ (qos, TRUE);
 
@@ -322,14 +272,11 @@ TEST (tensor_sink_test, signals)
   ASSERT_TRUE (_setup_pipeline (num_buffers));
 
   if (DBG) {
-    /* print logs */
-    g_object_set (g_test_data.sink, "silent", FALSE, NULL);
+    /** print logs */
+    g_object_set (g_test_data.sink, "silent", (gboolean) FALSE, NULL);
   }
 
-  /* enable emit-signal */
-  g_object_set (g_test_data.sink, "emit-signal", TRUE, NULL);
-
-  /* tensor sink signals */
+  /** tensor sink signals */
   handle_id = g_signal_connect (g_test_data.sink, "new-data",
       (GCallback) _new_data_cb, NULL);
   EXPECT_TRUE (handle_id > 0);
@@ -347,10 +294,10 @@ TEST (tensor_sink_test, signals)
   g_main_loop_run (g_test_data.loop);
   gst_element_set_state (g_test_data.pipeline, GST_STATE_NULL);
 
-  /* check eos message */
+  /** check eos message */
   EXPECT_EQ (g_test_data.status, TEST_EOS);
 
-  /* check received buffers and signals */
+  /** check received buffers and signals */
   EXPECT_EQ (g_test_data.received, num_buffers);
   EXPECT_EQ (g_test_data.start, TRUE);
   EXPECT_EQ (g_test_data.end, TRUE);
@@ -359,9 +306,9 @@ TEST (tensor_sink_test, signals)
 }
 
 /**
- * @brief Test for tensor sink render-rate.
+ * @brief Test for tensor sink signal-rate.
  */
-TEST (tensor_sink_test, render_rate)
+TEST (tensor_sink_test, signal_rate)
 {
   const guint num_buffers = 10;
   gulong handle_id;
@@ -369,30 +316,27 @@ TEST (tensor_sink_test, render_rate)
   ASSERT_TRUE (_setup_pipeline (num_buffers));
 
   if (DBG) {
-    /* print logs */
-    g_object_set (g_test_data.sink, "silent", FALSE, NULL);
+    /** print logs */
+    g_object_set (g_test_data.sink, "silent", (gboolean) FALSE, NULL);
   }
 
-  /* enable emit-signal */
-  g_object_set (g_test_data.sink, "emit-signal", TRUE, NULL);
+  /** set signal-rate */
+  g_object_set (g_test_data.sink, "signal-rate", (guint) 15, NULL);
 
-  /* set render-rate */
-  g_object_set (g_test_data.sink, "render-rate", (guint64) 15, NULL);
-
-  /* signal for new data */
+  /** signal for new data */
   handle_id = g_signal_connect (g_test_data.sink, "new-data",
       (GCallback) _new_data_cb, NULL);
   EXPECT_TRUE (handle_id > 0);
 
-  _print_log ("start pipeline for render-rate test");
+  _print_log ("start pipeline for signal-rate test");
   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 */
+  /** check eos message */
   EXPECT_EQ (g_test_data.status, TEST_EOS);
 
-  /* check received buffers */
+  /** check received buffers */
   EXPECT_TRUE (g_test_data.received < num_buffers);
 
   _free_test_data ();
@@ -410,16 +354,16 @@ TEST (tensor_sink_test, unknown_case)
   ASSERT_TRUE (_setup_pipeline (num_buffers));
 
   if (DBG) {
-    /* print logs */
-    g_object_set (g_test_data.sink, "silent", FALSE, NULL);
+    /** print logs */
+    g_object_set (g_test_data.sink, "silent", (gboolean) FALSE, NULL);
   }
 
-  /* try to set/get unknown property */
+  /** try to set/get unknown property */
   g_object_set (g_test_data.sink, "unknown-prop", 1, NULL);
   g_object_get (g_test_data.sink, "unknown-prop", &unknown, NULL);
   EXPECT_EQ (unknown, -1);
 
-  /* unknown signal */
+  /** unknown signal */
   handle_id = g_signal_connect (g_test_data.sink, "unknown-sig",
       (GCallback) _new_data_cb, NULL);
   EXPECT_EQ (handle_id, 0);
@@ -429,10 +373,53 @@ TEST (tensor_sink_test, unknown_case)
   g_main_loop_run (g_test_data.loop);
   gst_element_set_state (g_test_data.pipeline, GST_STATE_NULL);
 
-  /* check eos message */
+  /** check eos message */
   EXPECT_EQ (g_test_data.status, TEST_EOS);
 
-  /* check received buffers */
+  /** check received buffers */
+  EXPECT_EQ (g_test_data.received, 0);
+
+  _free_test_data ();
+}
+
+/**
+ * @brief Test for caps negotiation failed.
+ */
+TEST (tensor_sink_test, caps_error)
+{
+  const guint num_buffers = 10;
+  gchar *str_pipeline;
+
+  g_test_data.received = 0;
+  g_test_data.loop = g_main_loop_new (NULL, FALSE);
+
+  /** cannot link videoconvert and tensor_sink */
+  str_pipeline =
+      g_strdup_printf
+      ("videotestsrc num-buffers=%d ! video/x-raw,width=160,height=120,format=RGB,framerate=(fraction)30/1 ! "
+      "videoconvert ! tensor_sink name=test_sink", num_buffers);
+  g_test_data.pipeline = gst_parse_launch (str_pipeline, NULL);
+  g_free (str_pipeline);
+
+  g_test_data.bus = gst_element_get_bus (g_test_data.pipeline);
+  gst_bus_add_signal_watch (g_test_data.bus);
+  g_signal_connect (g_test_data.bus, "message", (GCallback) _message_cb, NULL);
+
+  g_test_data.sink =
+      gst_bin_get_by_name (GST_BIN (g_test_data.pipeline), "test_sink");
+
+  g_signal_connect (g_test_data.sink, "new-data", (GCallback) _new_data_cb,
+      NULL);
+
+  _print_log ("start pipeline for caps error test");
+  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 error message */
+  EXPECT_EQ (g_test_data.status, TEST_ERR_MESSAGE);
+
+  /** check received buffers */
   EXPECT_EQ (g_test_data.received, 0);
 
   _free_test_data ();