Doxygen Book
tensor_query_serversink.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-only */
13 #ifdef HAVE_CONFIG_H
14 #include <config.h>
15 #endif
16 
17 #include <string.h>
19 
20 GST_DEBUG_CATEGORY_STATIC (gst_tensor_query_serversink_debug);
21 #define GST_CAT_DEFAULT gst_tensor_query_serversink_debug
22 
23 #define DEFAULT_METALESS_FRAME_LIMIT 1
24 
28 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
29  GST_PAD_SINK,
30  GST_PAD_ALWAYS,
31  GST_STATIC_CAPS_ANY);
32 
33 enum
34 {
40 };
41 
42 #define gst_tensor_query_serversink_parent_class parent_class
43 G_DEFINE_TYPE (GstTensorQueryServerSink, gst_tensor_query_serversink,
44  GST_TYPE_BASE_SINK);
45 static GstStateChangeReturn gst_tensor_query_serversink_change_state (GstElement
46  * element, GstStateChange transition);
47 static void gst_tensor_query_serversink_set_property (GObject * object,
48  guint prop_id, const GValue * value, GParamSpec * pspec);
49 static void gst_tensor_query_serversink_get_property (GObject * object,
50  guint prop_id, GValue * value, GParamSpec * pspec);
51 static void gst_tensor_query_serversink_finalize (GObject * object);
52 
53 static GstFlowReturn gst_tensor_query_serversink_render (GstBaseSink * bsink,
54  GstBuffer * buf);
55 static gboolean gst_tensor_query_serversink_set_caps (GstBaseSink * basesink,
56  GstCaps * caps);
57 
61 static void
63 {
64  GObjectClass *gobject_class;
65  GstElementClass *gstelement_class;
66  GstBaseSinkClass *gstbasesink_class;
67 
68  gstbasesink_class = (GstBaseSinkClass *) klass;
69  gstelement_class = (GstElementClass *) gstbasesink_class;
70  gobject_class = (GObjectClass *) gstelement_class;
71 
72  gstelement_class->change_state = gst_tensor_query_serversink_change_state;
73  gobject_class->set_property = gst_tensor_query_serversink_set_property;
74  gobject_class->get_property = gst_tensor_query_serversink_get_property;
75  gobject_class->finalize = gst_tensor_query_serversink_finalize;
76 
77  g_object_class_install_property (gobject_class, PROP_CONNECT_TYPE,
78  g_param_spec_enum ("connect-type", "Connect Type",
79  "The connection type",
81  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
82  g_object_class_install_property (gobject_class, PROP_TIMEOUT,
83  g_param_spec_uint ("timeout", "Timeout",
84  "The timeout as seconds to maintain connection", 0,
86  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
87  g_object_class_install_property (gobject_class, PROP_ID,
88  g_param_spec_uint ("id", "ID",
89  "ID for distinguishing query servers.", 0,
90  G_MAXUINT, DEFAULT_SERVER_ID,
91  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
92  g_object_class_install_property (gobject_class, PROP_METALESS_FRAME_LIMIT,
93  g_param_spec_int ("limit", "Limit",
94  "Limits of the number of the buffers that the server cannot handle. "
95  "e.g., If the received buffer does not have a GstMetaQuery, the server cannot handle the buffer.",
97  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
98 
99  gst_element_class_add_pad_template (gstelement_class,
100  gst_static_pad_template_get (&sinktemplate));
101 
102  gst_element_class_set_static_metadata (gstelement_class,
103  "TensorQueryServerSink", "Sink/Tensor/Query",
104  "Send tensor data as a server over the network",
105  "Samsung Electronics Co., Ltd.");
106 
107  gstbasesink_class->set_caps = gst_tensor_query_serversink_set_caps;
108  gstbasesink_class->render = gst_tensor_query_serversink_render;
109 
110  GST_DEBUG_CATEGORY_INIT (gst_tensor_query_serversink_debug,
111  "tensor_query_serversink", 0, "Tensor Query Server Sink");
112 }
113 
117 static void
119 {
122  sink->sink_id = DEFAULT_SERVER_ID;
123  sink->metaless_frame_count = 0;
124 }
125 
129 static void
131 {
134  G_OBJECT_CLASS (parent_class)->finalize (object);
135 }
136 
140 static gboolean
142 {
143  gboolean ret;
144 
146  if (ret)
148 
149  return ret;
150 }
151 
155 static gboolean
157 {
158  gboolean ret;
159 
161  NULL);
162 
163  return ret;
164 }
165 
169 static GstStateChangeReturn
171  GstStateChange transition)
172 {
174  GstBaseSink *bsink = GST_BASE_SINK (element);
175  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
176  GstCaps *caps;
177 
178  switch (transition) {
179  case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
181  nns_loge ("Failed to change state from PAUSED to PLAYING.");
182  return GST_STATE_CHANGE_FAILURE;
183  }
184 
185  caps = gst_pad_peer_query_caps (GST_BASE_SINK_PAD (bsink), NULL);
187  gst_caps_unref (caps);
188  break;
189  case GST_STATE_CHANGE_READY_TO_PAUSED:
191  nns_loge ("Failed to change state from READY to PAUSED.");
192  return GST_STATE_CHANGE_FAILURE;
193  }
194  break;
195  default:
196  break;
197  }
198 
199  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
200  if (ret == GST_STATE_CHANGE_FAILURE) {
201  nns_loge ("Failed to change state");
202  return ret;
203  }
204 
205  switch (transition) {
206  case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
208  break;
209  default:
210  break;
211  }
212 
213  return ret;
214 }
215 
219 static void
220 gst_tensor_query_serversink_set_property (GObject * object, guint prop_id,
221  const GValue * value, GParamSpec * pspec)
222 {
224 
225  switch (prop_id) {
226  case PROP_CONNECT_TYPE:
227  serversink->connect_type = g_value_get_enum (value);
228  break;
229  case PROP_TIMEOUT:
230  serversink->timeout = g_value_get_uint (value);
231  break;
232  case PROP_ID:
233  serversink->sink_id = g_value_get_uint (value);
234  break;
236  serversink->metaless_frame_limit = g_value_get_int (value);
237  break;
238  default:
239  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
240  break;
241  }
242 }
243 
247 static void
248 gst_tensor_query_serversink_get_property (GObject * object, guint prop_id,
249  GValue * value, GParamSpec * pspec)
250 {
252 
253  switch (prop_id) {
254  case PROP_CONNECT_TYPE:
255  g_value_set_enum (value, serversink->connect_type);
256  break;
257  case PROP_TIMEOUT:
258  g_value_set_uint (value, serversink->timeout);
259  break;
260  case PROP_ID:
261  g_value_set_uint (value, serversink->sink_id);
262  break;
264  g_value_set_int (value, serversink->metaless_frame_limit);
265  break;
266  default:
267  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
268  break;
269  }
270 }
271 
275 static gboolean
276 gst_tensor_query_serversink_set_caps (GstBaseSink * bsink, GstCaps * caps)
277 {
279  gchar *caps_str, *new_caps_str;
280 
281  caps_str = gst_caps_to_string (caps);
282 
283  new_caps_str = g_strdup_printf ("@query_server_sink_caps@%s", caps_str);
284  gst_tensor_query_server_set_caps (sink->sink_id, new_caps_str);
285 
286  g_free (new_caps_str);
287  g_free (caps_str);
288 
289  return TRUE;
290 }
291 
295 static GstFlowReturn
296 gst_tensor_query_serversink_render (GstBaseSink * bsink, GstBuffer * buf)
297 {
299  GstMetaQuery *meta_query;
300 
301  meta_query = gst_buffer_get_meta_query (buf);
302  if (meta_query) {
303  sink->metaless_frame_count = 0;
304 
305  if (!gst_tensor_query_server_send_buffer (sink->sink_id, buf)) {
306  nns_loge ("Failed to send buffer to edge device in server sink.");
307  return GST_FLOW_ERROR;
308  }
309  } else {
310  nns_logw ("Cannot get tensor query meta. Drop buffers!\n");
311  sink->metaless_frame_count++;
312 
313  if (sink->metaless_frame_count >= sink->metaless_frame_limit) {
314  nns_logw ("Cannot get tensor query meta. Stop the query server!\n"
315  "There are elements that are not available on the query server.\n"
316  "Please check available elements on the server."
317  "See: https://github.com/nnstreamer/nnstreamer/wiki/Available-elements-on-query-server");
318  return GST_FLOW_ERROR;
319  }
320  }
321 
322  return GST_FLOW_OK;
323 }
PROP_0
@ PROP_0
Definition: tensor_query_serversink.c:35
gst_tensor_query_server_add_data
gboolean gst_tensor_query_server_add_data(const guint id)
Add nnstreamer edge server handle into hash table.
Definition: tensor_query_server.c:77
_GstTensorQueryServerSink
GstTensorQueryServerSink data structure.
Definition: tensor_query_serversink.h:40
_GstTensorQueryServerSink::connect_type
nns_edge_connect_type_e connect_type
Definition: tensor_query_serversink.h:49
G_DEFINE_TYPE
G_DEFINE_TYPE(GstTensorQueryServerSink, gst_tensor_query_serversink, GST_TYPE_BASE_SINK)
_gst_tensor_query_serversink_playing
static gboolean _gst_tensor_query_serversink_playing(GstTensorQueryServerSink *sink)
start processing of query_serversink
Definition: tensor_query_serversink.c:156
DEFAULT_SERVER_ID
#define DEFAULT_SERVER_ID
Definition: tensor_query_server.h:22
gst_tensor_query_serversink_set_property
static void gst_tensor_query_serversink_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
set property
Definition: tensor_query_serversink.c:220
DEFAULT_METALESS_FRAME_LIMIT
#define DEFAULT_METALESS_FRAME_LIMIT
Definition: tensor_query_serversink.c:23
GstMetaQuery
GstMetaQuery meta structure.
Definition: tensor_meta.h:26
sinktemplate
static GstStaticPadTemplate sinktemplate
the capabilities of the inputs.
Definition: tensor_query_serversink.c:28
gst_tensor_query_serversink_set_caps
static gboolean gst_tensor_query_serversink_set_caps(GstBaseSink *basesink, GstCaps *caps)
An implementation of the set_caps vmethod in GstBaseSinkClass.
Definition: tensor_query_serversink.c:276
GST_TYPE_QUERY_CONNECT_TYPE
#define GST_TYPE_QUERY_CONNECT_TYPE
Definition: tensor_query_common.h:35
g_free
g_free(self->option[(opnum) - 1])
opnum: \
gst_tensor_query_server_set_configured
void gst_tensor_query_server_set_configured(const guint id)
set query server sink configured.
Definition: tensor_query_server.c:322
gst_buffer_get_meta_query
#define gst_buffer_get_meta_query(b)
Definition: tensor_meta.h:44
_GstTensorQueryServerSink::metaless_frame_count
gint metaless_frame_count
Definition: tensor_query_serversink.h:47
PROP_METALESS_FRAME_LIMIT
@ PROP_METALESS_FRAME_LIMIT
Definition: tensor_query_serversink.c:39
tensor_query_serversink.h
GStreamer plugin to handle tensor query_server sink.
QUERY_DEFAULT_TIMEOUT_SEC
#define QUERY_DEFAULT_TIMEOUT_SEC
Default timeout, in seconds.
Definition: tensor_query_common.h:28
gst_tensor_query_serversink_render
static GstFlowReturn gst_tensor_query_serversink_render(GstBaseSink *bsink, GstBuffer *buf)
render buffer, send buffer to client
Definition: tensor_query_serversink.c:296
_gst_tensor_query_serversink_start
static gboolean _gst_tensor_query_serversink_start(GstTensorQueryServerSink *sink)
start processing of query_serversink
Definition: tensor_query_serversink.c:141
TRUE
return TRUE
Definition: gsttensor_if.c:897
PROP_ID
@ PROP_ID
Definition: tensor_query_serversink.c:37
nns_loge
#define nns_loge
Definition: nnstreamer_log.h:142
gst_tensor_query_server_remove_data
void gst_tensor_query_server_remove_data(const guint id)
Remove GstTensorQueryServer.
Definition: tensor_query_server.c:280
DEFAULT_CONNECT_TYPE
#define DEFAULT_CONNECT_TYPE
Definition: edge_common.h:27
PROP_CONNECT_TYPE
@ PROP_CONNECT_TYPE
Definition: tensor_query_serversink.c:36
gst_tensor_query_serversink_get_property
static void gst_tensor_query_serversink_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
get property
Definition: tensor_query_serversink.c:248
_GstTensorQueryServerSinkClass
GstTensorQueryServerSinkClass data structure.
Definition: tensor_query_serversink.h:55
_GstTensorQueryServerSink::metaless_frame_limit
gint metaless_frame_limit
Definition: tensor_query_serversink.h:46
gst_tensor_query_serversink_class_init
static void gst_tensor_query_serversink_class_init(GstTensorQueryServerSinkClass *klass)
initialize the class
Definition: tensor_query_serversink.c:62
gst_tensor_query_serversink_init
static void gst_tensor_query_serversink_init(GstTensorQueryServerSink *sink)
initialize the new element
Definition: tensor_query_serversink.c:118
_GstTensorQueryServerSink::sink_id
guint sink_id
Definition: tensor_query_serversink.h:43
nns_logw
#define nns_logw
Definition: nnstreamer_log.h:141
gst_tensor_query_server_release_edge_handle
void gst_tensor_query_server_release_edge_handle(const guint id)
Release nnstreamer edge handle of query server.
Definition: tensor_query_server.c:258
GST_TENSOR_QUERY_SERVERSINK
#define GST_TENSOR_QUERY_SERVERSINK(obj)
Definition: tensor_query_serversink.h:25
PROP_TIMEOUT
@ PROP_TIMEOUT
Definition: tensor_query_serversink.c:38
gst_tensor_query_server_prepare
gboolean gst_tensor_query_server_prepare(const guint id, nns_edge_connect_type_e connect_type, GstTensorQueryEdgeInfo *edge_info)
Prepare edge connection and its handle.
Definition: tensor_query_server.c:114
gst_tensor_query_server_send_buffer
gboolean gst_tensor_query_server_send_buffer(const guint id, GstBuffer *buffer)
Send buffer to connected edge device.
Definition: tensor_query_server.c:183
gst_tensor_query_serversink_finalize
static void gst_tensor_query_serversink_finalize(GObject *object)
finalize the object
Definition: tensor_query_serversink.c:130
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(gst_tensor_query_serversink_debug)
gst_tensor_query_serversink_change_state
static GstStateChangeReturn gst_tensor_query_serversink_change_state(GstElement *element, GstStateChange transition)
Change state of query server sink.
Definition: tensor_query_serversink.c:170
gst_tensor_query_server_set_caps
void gst_tensor_query_server_set_caps(const guint id, const gchar *caps_str)
set query server caps.
Definition: tensor_query_server.c:342
_GstTensorQueryServerSink::timeout
guint timeout
Definition: tensor_query_serversink.h:45