73 #define GST_CAT_DEFAULT gst_tensor_demux_debug
78 #define CAPS_STRING_SINK GST_TENSORS_CAP_MAKE ("{ static, flexible }")
83 #define CAPS_STRING_SRC GST_TENSOR_CAP_DEFAULT ";" GST_TENSORS_CAP_MAKE ("{ static, flexible }")
96 static GstStaticPadTemplate
src_templ = GST_STATIC_PAD_TEMPLATE (
"src_%u",
102 static GstStaticPadTemplate
sink_templ = GST_STATIC_PAD_TEMPLATE (
"sink",
113 GstStateChange transition);
115 const GValue * value, GParamSpec * pspec);
117 GValue * value, GParamSpec * pspec);
119 #define gst_tensor_demux_parent_class parent_class
129 GObjectClass *gobject_class;
130 GstElementClass *gstelement_class;
132 GST_DEBUG_CATEGORY_INIT (gst_tensor_demux_debug,
"tensor_demux", 0,
133 "Element to demux tensors to tensor stream");
135 gobject_class = (GObjectClass *) klass;
136 gstelement_class = (GstElementClass *) klass;
138 parent_class = g_type_class_peek_parent (klass);
144 g_object_class_install_property (gobject_class,
PROP_SILENT,
145 g_param_spec_boolean (
"silent",
"Silent",
"Produce verbose output ?",
146 TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
149 g_param_spec_string (
"tensorpick",
"TensorPick",
150 "Choose nth tensor among tensors ?",
"",
151 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
153 gstelement_class->change_state =
156 gst_element_class_add_pad_template (gstelement_class,
158 gst_element_class_add_pad_template (gstelement_class,
159 gst_static_pad_template_get (&
src_templ));
161 gst_element_class_set_details_simple (gstelement_class,
164 "Demux tensors stream to other/tensor stream",
165 "Jijoong Moon <jijoong.moon@samsung.com>");
178 gst_pad_new_from_static_template (&
sink_templ,
"sink");
179 gst_element_add_pad (GST_ELEMENT_CAST (tensor_demux), tensor_demux->
sinkpad);
180 gst_pad_set_chain_function (tensor_demux->
sinkpad,
182 gst_pad_set_event_function (tensor_demux->
sinkpad,
201 while (tensor_demux->
srcpads != NULL) {
203 gst_element_remove_pad (GST_ELEMENT (tensor_demux), tensor_pad->
pad);
206 g_slist_delete_link (tensor_demux->
srcpads, tensor_demux->
srcpads);
225 G_OBJECT_CLASS (parent_class)->dispose (
object);
237 switch (GST_EVENT_TYPE (event)) {
241 gst_event_parse_caps (event, &caps);
247 GST_ELEMENT_ERROR (tensor_demux, STREAM, WRONG_TYPE,
248 (
"This stream contains no valid stremas."),
249 (
"Got EOS before adding any pads"));
250 gst_event_unref (event);
258 return gst_pad_event_default (pad, parent, event);
276 gchar *selected_tensor;
282 selected_tensor = (gchar *) g_list_nth_data (tensor_demux->
tensorpick, nth);
283 strv = g_strsplit_set (selected_tensor,
":+", -1);
284 num = g_strv_length (strv);
286 for (i = 0; i < num; i++) {
287 idx = (guint) g_ascii_strtoll (strv[i], NULL, 10);
330 gboolean * created,
const guint nth,
const guint total)
332 GstElement *element = GST_ELEMENT_CAST (tensor_demux);
333 g_autofree gchar *element_name = gst_element_get_name (element);
340 GstCaps *caps = NULL;
346 if (nth == pad->
nth) {
357 GST_DEBUG_OBJECT (tensor_demux,
"creating pad: %d(%dth)",
360 name = g_strdup_printf (
"src_%u", tensor_demux->
num_srcpads);
361 pad = gst_pad_new_from_static_template (&
src_templ, name);
362 stream_id = gst_pad_create_stream_id_printf (pad, element,
363 "%s-nnsdemux-%s-%08x", element_name, name, g_random_int ());
366 tensorpad->
pad = pad;
367 tensorpad->
nth = nth;
369 tensorpad->
last_ts = GST_CLOCK_TIME_NONE;
371 tensor_demux->
srcpads = g_slist_append (tensor_demux->
srcpads, tensorpad);
374 gst_pad_use_fixed_caps (pad);
375 gst_pad_set_active (pad,
TRUE);
376 gst_element_add_pad (GST_ELEMENT_CAST (tensor_demux), pad);
380 gst_pad_get_sticky_event (tensor_demux->
sinkpad, GST_EVENT_STREAM_START,
384 gst_event_parse_group_id (event, &tensor_demux->
group_id);
385 gst_event_unref (event);
388 tensor_demux->
group_id = gst_util_group_id_next ();
392 event = gst_event_new_stream_start (stream_id);
394 gst_event_set_group_id (event, tensor_demux->
group_id);
396 gst_pad_store_sticky_event (pad, event);
398 gst_event_unref (event);
404 gst_pad_set_caps (pad, caps);
405 gst_caps_unref (caps);
407 GST_WARNING_OBJECT (tensor_demux,
"Unable to set pad caps");
415 GST_DEBUG_OBJECT (tensor_demux,
"TensorPick is set! : %dth tensor\n", nth);
417 gst_element_no_more_pads (GST_ELEMENT_CAST (tensor_demux));
439 if (ret != GST_FLOW_NOT_LINKED)
442 for (walk = tensor_demux->
srcpads; walk; walk = g_slist_next (walk)) {
445 if (ret != GST_FLOW_NOT_LINKED)
458 guint num_tensors, num_srcs, i, idx;
459 GstFlowReturn res = GST_FLOW_OK;
478 GST_DEBUG_OBJECT (tensor_demux,
" Number of Tensors: %d", num_tensors);
480 num_srcs = num_tensors;
482 num_srcs = g_list_length (tensor_demux->
tensorpick);
486 for (i = 0; i < num_srcs; i++) {
495 outbuf = gst_buffer_new ();
499 gchar **strv = g_strsplit_set ((gchar *) list->data,
":+", -1);
501 num = g_strv_length (strv);
502 for (j = 0; j < num; j++) {
503 idx = (guint) g_ascii_strtoll (strv[j], NULL, 10);
509 gst_buffer_unref (outbuf);
510 res = GST_FLOW_ERROR;
521 gst_buffer_unref (outbuf);
522 res = GST_FLOW_ERROR;
527 ts = GST_BUFFER_TIMESTAMP (buf);
531 gst_segment_init (&segment, GST_FORMAT_TIME);
532 gst_pad_push_event (srcpad->
pad, gst_event_new_segment (&segment));
535 outbuf = gst_buffer_make_writable (outbuf);
538 gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
540 if (srcpad->
last_ts == GST_CLOCK_TIME_NONE || srcpad->
last_ts != ts) {
543 GST_DEBUG_OBJECT (tensor_demux,
"invalid timestamp %" GST_TIME_FORMAT,
547 GST_DEBUG_OBJECT (tensor_demux,
548 "pushing buffer with timestamp %" GST_TIME_FORMAT,
549 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
550 res = gst_pad_push (srcpad->
pad, outbuf);
553 if (res != GST_FLOW_OK)
558 gst_buffer_unref (buf);
565 static GstStateChangeReturn
569 GstStateChangeReturn ret;
571 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
572 if (ret == GST_STATE_CHANGE_FAILURE)
574 switch (transition) {
575 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
577 case GST_STATE_CHANGE_PAUSED_TO_READY:
582 case GST_STATE_CHANGE_READY_TO_NULL:
596 const GValue * value, GParamSpec * pspec)
601 filter->
silent = g_value_get_boolean (value);
606 const gchar *param = g_value_get_string (value);
607 gchar **strv = g_strsplit_set (param,
",.;/", -1);
608 guint num = g_strv_length (strv);
615 for (i = 0; i < num; i++) {
616 gchar *tmp = g_strdup (strv[i]);
623 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, prop_id, pspec);
633 GValue * value, GParamSpec * pspec)
638 g_value_set_boolean (value, filter->
silent);
644 GPtrArray *arr = g_ptr_array_new ();
647 for (list = filter->
tensorpick; list != NULL; list = list->next) {
648 g_ptr_array_add (arr, g_strdup_printf (
"%s", (gchar *) list->data));
650 g_ptr_array_add (arr, NULL);
651 strings = (gchar **) g_ptr_array_free (arr,
FALSE);
652 p = g_strjoinv (
",", strings);
653 g_strfreev (strings);
654 g_value_take_string (value, p);
658 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, prop_id, pspec);