Doxygen Book
gstjoin.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-only */
32 #include "gstjoin.h"
33 
34 GST_DEBUG_CATEGORY_STATIC (join_debug);
35 #define GST_CAT_DEFAULT join_debug
36 
37 #define GST_JOIN_GET_LOCK(sel) (&((GstJoin*)(sel))->lock)
38 #define GST_JOIN_GET_COND(sel) (&((GstJoin*)(sel))->cond)
39 #define GST_JOIN_LOCK(sel) (g_mutex_lock (GST_JOIN_GET_LOCK(sel)))
40 #define GST_JOIN_UNLOCK(sel) (g_mutex_unlock (GST_JOIN_GET_LOCK(sel)))
41 #define GST_JOIN_WAIT(sel) (g_cond_wait (GST_JOIN_GET_COND(sel), \
42  GST_JOIN_GET_LOCK(sel)))
43 
47 static GstStaticPadTemplate gst_join_sink_factory =
48 GST_STATIC_PAD_TEMPLATE ("sink_%u",
49  GST_PAD_SINK,
50  GST_PAD_REQUEST,
51  GST_STATIC_CAPS_ANY);
52 
56 static GstStaticPadTemplate gst_join_src_factory =
57 GST_STATIC_PAD_TEMPLATE ("src",
58  GST_PAD_SRC,
59  GST_PAD_ALWAYS,
60  GST_STATIC_CAPS_ANY);
61 
62 enum
63 {
67 };
68 
69 static GstPad *gst_join_get_active_sinkpad (GstJoin * sel);
70 static GstPad *gst_join_get_linked_pad (GstJoin * sel,
71  GstPad * pad, gboolean strict);
72 static gboolean gst_join_set_active_pad (GstJoin * self, GstPad * pad);
73 
74 #define GST_TYPE_JOIN_PAD \
75  (gst_join_pad_get_type())
76 #define GST_JOIN_PAD(obj) \
77  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_JOIN_PAD, GstJoinPad))
78 #define GST_JOIN_PAD_CLASS(klass) \
79  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_JOIN_PAD, GstJoinPadClass))
80 #define GST_IS_JOIN_PAD(obj) \
81  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_JOIN_PAD))
82 #define GST_IS_JOIN_PAD_CLASS(klass) \
83  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_JOIN_PAD))
84 #define GST_JOIN_PAD_CAST(obj) \
85  ((GstJoinPad *)(obj))
86 
87 typedef struct _GstJoinPad GstJoinPad;
89 
94 {
95  GstPad parent;
96 
97  guint group_id; /* Group ID from the last stream-start */
98 
99  GstSegment segment; /* the current segment on the pad */
100  guint32 segment_seqnum; /* sequence number of the current segment */
101 };
102 
107 {
108  GstPadClass parent;
109 };
110 
111 GType gst_join_pad_get_type (void);
112 static void gst_join_pad_finalize (GObject * object);
113 static void gst_join_pad_reset (GstJoinPad * pad);
114 static gboolean gst_join_pad_event (GstPad * pad, GstObject * parent,
115  GstEvent * event);
116 static gboolean gst_join_pad_query (GstPad * pad, GstObject * parent,
117  GstQuery * query);
118 static GstIterator *gst_join_pad_iterate_linked_pads (GstPad * pad,
119  GstObject * parent);
120 static GstFlowReturn gst_join_pad_chain (GstPad * pad, GstObject * parent,
121  GstBuffer * buf);
122 
123 G_DEFINE_TYPE (GstJoinPad, gst_join_pad, GST_TYPE_PAD);
124 
128 static void
130 {
131  GObjectClass *gobject_class;
132 
133  gobject_class = (GObjectClass *) klass;
134 
135  gobject_class->finalize = gst_join_pad_finalize;
136 }
137 
141 static void
143 {
144  gst_join_pad_reset (pad);
145 }
146 
150 static void
151 gst_join_pad_finalize (GObject * object)
152 {
153  G_OBJECT_CLASS (gst_join_pad_parent_class)->finalize (object);
154 }
155 
160 static void
162 {
163  GST_OBJECT_LOCK (pad);
164  gst_segment_init (&pad->segment, GST_FORMAT_UNDEFINED);
165  GST_OBJECT_UNLOCK (pad);
166 }
167 
172 static GstIterator *
173 gst_join_pad_iterate_linked_pads (GstPad * pad, GstObject * parent)
174 {
175  GstJoin *sel;
176  GstPad *otherpad;
177  GstIterator *it = NULL;
178  GValue val = { 0, };
179 
180  sel = GST_JOIN (parent);
181 
182  otherpad = gst_join_get_linked_pad (sel, pad, TRUE);
183  if (otherpad) {
184  g_value_init (&val, GST_TYPE_PAD);
185  g_value_set_object (&val, otherpad);
186  it = gst_iterator_new_single (GST_TYPE_PAD, &val);
187  g_value_unset (&val);
188  gst_object_unref (otherpad);
189  }
190 
191  return it;
192 }
193 
197 static gboolean
198 forward_sticky_events (GstPad * sinkpad, GstEvent ** event, gpointer user_data)
199 {
200  GstJoin *sel = GST_JOIN (user_data);
201 
202  GST_DEBUG_OBJECT (sinkpad, "forward sticky event %" GST_PTR_FORMAT, *event);
203 
204  if (GST_EVENT_TYPE (*event) == GST_EVENT_SEGMENT) {
205  GstSegment *seg = &GST_JOIN_PAD (sinkpad)->segment;
206  GstEvent *e;
207 
208  e = gst_event_new_segment (seg);
209  gst_event_set_seqnum (e, GST_JOIN_PAD_CAST (sinkpad)->segment_seqnum);
210 
211  gst_pad_push_event (sel->srcpad, e);
212  } else if (GST_EVENT_TYPE (*event) == GST_EVENT_STREAM_START
213  && !sel->have_group_id) {
214  GstEvent *tmp =
215  gst_pad_get_sticky_event (sel->srcpad, GST_EVENT_STREAM_START, 0);
216 
217  /* Only push stream-start once if not all our streams have a stream-id */
218  if (!tmp) {
219  gst_pad_push_event (sel->srcpad, gst_event_ref (*event));
220  } else {
221  gst_event_unref (tmp);
222  }
223  } else {
224  gst_pad_push_event (sel->srcpad, gst_event_ref (*event));
225  }
226  return TRUE;
227 }
228 
232 static gboolean
233 gst_join_pad_event (GstPad * pad, GstObject * parent, GstEvent * event)
234 {
235  gboolean res = TRUE;
236  gboolean forward;
237  GstJoin *sel;
238  GstJoinPad *selpad;
239  GstPad *active_sinkpad;
240 
241  sel = GST_JOIN (parent);
242  selpad = GST_JOIN_PAD_CAST (pad);
243  GST_DEBUG_OBJECT (selpad, "received event %" GST_PTR_FORMAT, event);
244 
245  GST_JOIN_LOCK (sel);
246 
247  active_sinkpad = gst_join_get_active_sinkpad (sel);
248 
249  /* only forward if we are dealing with the active sinkpad */
250  forward = (pad == active_sinkpad);
251 
252  switch (GST_EVENT_TYPE (event)) {
253  case GST_EVENT_CAPS:
254  {
255  GstCaps *prev_caps, *new_caps;
256 
257  if (!(prev_caps = gst_pad_get_current_caps (active_sinkpad)))
258  break;
259 
260  gst_event_parse_caps (event, &new_caps);
261 
262  if (!gst_caps_is_equal (prev_caps, new_caps)) {
263  GST_ERROR_OBJECT (sel, "Capabilities of the sinks should be the same.");
264  res = FALSE;
265  }
266 
267  gst_caps_unref (prev_caps);
268 
269  break;
270  }
271  case GST_EVENT_STREAM_START:{
272  if (!gst_event_parse_group_id (event, &selpad->group_id)) {
273  sel->have_group_id = FALSE;
274  selpad->group_id = 0;
275  }
276  break;
277  }
278  case GST_EVENT_SEGMENT:
279  {
280  gst_event_copy_segment (event, &selpad->segment);
281  selpad->segment_seqnum = gst_event_get_seqnum (event);
282 
283  GST_DEBUG_OBJECT (pad, "configured SEGMENT %" GST_SEGMENT_FORMAT,
284  &selpad->segment);
285  break;
286  }
287  default:
288  break;
289  }
290  GST_JOIN_UNLOCK (sel);
291 
292  if (forward) {
293  GST_DEBUG_OBJECT (pad, "forwarding event");
294  res = gst_pad_push_event (sel->srcpad, event);
295  } else {
296  gst_event_unref (event);
297  }
298 
299  return res;
300 }
301 
306 static gboolean
307 gst_join_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
308 {
309  gboolean res = FALSE;
310  GstJoin *self = (GstJoin *) parent;
311 
312  switch (GST_QUERY_TYPE (query)) {
313  case GST_QUERY_CAPS:
314  case GST_QUERY_POSITION:
315  case GST_QUERY_DURATION:
316  case GST_QUERY_CONTEXT:
321  res = gst_pad_peer_query (self->srcpad, query);
322  break;
323  case GST_QUERY_ALLOCATION:{
324  GstPad *active_sinkpad;
325  GstJoin *sel = GST_JOIN (parent);
326 
332  if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
333  GST_JOIN_LOCK (sel);
334  active_sinkpad = gst_join_get_active_sinkpad (sel);
335  GST_JOIN_UNLOCK (sel);
336 
337  if (pad != active_sinkpad) {
338  res = FALSE;
339  goto done;
340  }
341  }
342  }
343  /* fall through */
344  default:
345  res = gst_pad_query_default (pad, parent, query);
346  break;
347  }
348 
349 done:
350  return res;
351 }
352 
356 static GstFlowReturn
357 gst_join_pad_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
358 {
359  GstJoin *sel;
360  GstFlowReturn res;
361  GstPad *active_sinkpad;
362  GstPad *prev_active_sinkpad = NULL;
363  GstJoinPad *selpad;
364 
365  sel = GST_JOIN (parent);
366  selpad = GST_JOIN_PAD_CAST (pad);
367  GST_DEBUG_OBJECT (selpad,
368  "entering chain for buf %p with timestamp %" GST_TIME_FORMAT, buf,
369  GST_TIME_ARGS (GST_BUFFER_PTS (buf)));
370 
371  GST_JOIN_LOCK (sel);
372 
373  GST_LOG_OBJECT (pad, "getting active pad");
374 
375  prev_active_sinkpad =
376  sel->active_sinkpad ? gst_object_ref (sel->active_sinkpad) : NULL;
377 
378  if (sel->active_sinkpad != pad) {
379  gst_join_set_active_pad (sel, pad);
380  }
381  active_sinkpad = pad;
382 
383  /* update the segment on the srcpad */
384  if (GST_BUFFER_PTS_IS_VALID (buf)) {
385  GstClockTime start_time = GST_BUFFER_PTS (buf);
386 
387  GST_LOG_OBJECT (pad, "received start time %" GST_TIME_FORMAT,
388  GST_TIME_ARGS (start_time));
389  if (GST_BUFFER_DURATION_IS_VALID (buf))
390  GST_LOG_OBJECT (pad, "received end time %" GST_TIME_FORMAT,
391  GST_TIME_ARGS (start_time + GST_BUFFER_DURATION (buf)));
392 
393  GST_OBJECT_LOCK (pad);
394  selpad->segment.position = start_time;
395  GST_OBJECT_UNLOCK (pad);
396  }
397 
398  GST_JOIN_UNLOCK (sel);
399 
400  /* if we have a pending events, push them now */
401  if (G_UNLIKELY (prev_active_sinkpad != active_sinkpad)) {
402  gst_pad_sticky_events_foreach (GST_PAD_CAST (selpad), forward_sticky_events,
403  sel);
404  }
405 
406  /* forward */
407  GST_LOG_OBJECT (pad, "Forwarding buffer %p with timestamp %" GST_TIME_FORMAT,
408  buf, GST_TIME_ARGS (GST_BUFFER_PTS (buf)));
409 
410  res = gst_pad_push (sel->srcpad, buf);
411  GST_LOG_OBJECT (pad, "Buffer %p forwarded result=%d", buf, res);
412 
413  if (prev_active_sinkpad)
414  gst_object_unref (prev_active_sinkpad);
415  prev_active_sinkpad = NULL;
416 
417  return res;
418 }
419 
420 static void gst_join_dispose (GObject * object);
421 static void gst_join_finalize (GObject * object);
422 
423 static void gst_join_get_property (GObject * object,
424  guint prop_id, GValue * value, GParamSpec * pspec);
425 static GstPad *gst_join_request_new_pad (GstElement * element,
426  GstPadTemplate * templ, const gchar * unused, const GstCaps * caps);
427 
428 #define gst_join_parent_class parent_class
429 G_DEFINE_TYPE_WITH_CODE (GstJoin, gst_join, GST_TYPE_ELEMENT,
430  GST_DEBUG_CATEGORY_INIT (join_debug,
431  "join", 0, "An input stream join element"));
432 
436 static void
438 {
439  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
440  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
441 
442  gobject_class->dispose = gst_join_dispose;
443  gobject_class->finalize = gst_join_finalize;
444 
445  gobject_class->get_property = gst_join_get_property;
446 
447  g_object_class_install_property (gobject_class, PROP_N_PADS,
448  g_param_spec_uint ("n-pads", "Number of Pads",
449  "The number of sink pads", 0, G_MAXUINT, 0,
450  G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
451 
452  g_object_class_install_property (gobject_class, PROP_ACTIVE_PAD,
453  g_param_spec_object ("active-pad", "Active pad",
454  "The currently active sink pad", GST_TYPE_PAD,
455  G_PARAM_READABLE | GST_PARAM_MUTABLE_PLAYING |
456  G_PARAM_STATIC_STRINGS));
457 
458  gst_element_class_set_static_metadata (gstelement_class, "Input join",
459  "Generic", "N-to-1 input stream join",
460  "Gichan Jang <gichan2.jang@samsung.com>, ");
461 
462  gst_element_class_add_static_pad_template (gstelement_class,
464  gst_element_class_add_static_pad_template (gstelement_class,
466 
467  gstelement_class->request_new_pad = gst_join_request_new_pad;
468 }
469 
473 static void
475 {
476  sel->srcpad = gst_pad_new ("src", GST_PAD_SRC);
477  gst_pad_set_iterate_internal_links_function (sel->srcpad,
478  GST_DEBUG_FUNCPTR (gst_join_pad_iterate_linked_pads));
479  GST_OBJECT_FLAG_SET (sel->srcpad, GST_PAD_FLAG_PROXY_CAPS);
480  gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad);
481  /* sinkpad management */
482  sel->active_sinkpad = NULL;
483  sel->padcount = 0;
484  sel->have_group_id = TRUE;
485 
486  g_mutex_init (&sel->lock);
487  g_cond_init (&sel->cond);
488 }
489 
493 static void
494 gst_join_dispose (GObject * object)
495 {
496  GstJoin *sel = GST_JOIN (object);
497 
498  if (sel->active_sinkpad) {
499  gst_object_unref (sel->active_sinkpad);
500  sel->active_sinkpad = NULL;
501  }
502  G_OBJECT_CLASS (parent_class)->dispose (object);
503 }
504 
508 static void
509 gst_join_finalize (GObject * object)
510 {
511  GstJoin *sel = GST_JOIN (object);
512 
513  g_mutex_clear (&sel->lock);
514  g_cond_clear (&sel->cond);
515 
516  G_OBJECT_CLASS (parent_class)->finalize (object);
517 }
518 
524 static gboolean
525 gst_join_set_active_pad (GstJoin * self, GstPad * pad)
526 {
527  GstJoinPad *old, *new;
528  GstPad **active_pad_p;
529 
530  if (pad == self->active_sinkpad)
531  return FALSE;
532 
533  /* guard against users setting a src pad or foreign pad as active pad */
534  if (pad != NULL) {
535  g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
536  g_return_val_if_fail (GST_IS_JOIN_PAD (pad), FALSE);
537  g_return_val_if_fail (GST_PAD_PARENT (pad) == GST_ELEMENT_CAST (self),
538  FALSE);
539  }
540 
541  old = GST_JOIN_PAD_CAST (self->active_sinkpad);
542  new = GST_JOIN_PAD_CAST (pad);
543 
544  GST_DEBUG_OBJECT (self, "setting active pad to %s:%s",
545  GST_DEBUG_PAD_NAME (new));
546 
547  active_pad_p = &self->active_sinkpad;
548  gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad));
549 
550  if (old && old != new)
551  gst_pad_push_event (GST_PAD_CAST (old), gst_event_new_reconfigure ());
552  if (new)
553  gst_pad_push_event (GST_PAD_CAST (new), gst_event_new_reconfigure ());
554 
555  GST_DEBUG_OBJECT (self, "New active pad is %" GST_PTR_FORMAT,
556  self->active_sinkpad);
557 
558  return TRUE;
559 }
560 
564 static void
565 gst_join_get_property (GObject * object, guint prop_id,
566  GValue * value, GParamSpec * pspec)
567 {
568  GstJoin *sel = GST_JOIN (object);
569 
570  switch (prop_id) {
571  case PROP_N_PADS:
572  GST_JOIN_LOCK (object);
573  g_value_set_uint (value, sel->n_pads);
574  GST_JOIN_UNLOCK (object);
575  break;
576  case PROP_ACTIVE_PAD:
577  GST_JOIN_LOCK (object);
578  g_value_set_object (value, sel->active_sinkpad);
579  GST_JOIN_UNLOCK (object);
580  break;
581  default:
582  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
583  break;
584  }
585 }
586 
590 static GstPad *
591 gst_join_get_linked_pad (GstJoin * sel, GstPad * pad, gboolean strict)
592 {
593  GstPad *otherpad = NULL;
594 
595  GST_JOIN_LOCK (sel);
596  if (pad == sel->srcpad)
597  otherpad = sel->active_sinkpad;
598  else if (pad == sel->active_sinkpad || !strict)
599  otherpad = sel->srcpad;
600  if (otherpad)
601  gst_object_ref (otherpad);
602  GST_JOIN_UNLOCK (sel);
603 
604  return otherpad;
605 }
606 
611 static GstPad *
613 {
614  GstPad *active_sinkpad;
615 
616  active_sinkpad = sel->active_sinkpad;
617  if (active_sinkpad == NULL) {
618  GValue item = G_VALUE_INIT;
619  GstIterator *iter = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (sel));
620  GstIteratorResult ires;
621 
622  while ((ires = gst_iterator_next (iter, &item)) == GST_ITERATOR_RESYNC)
623  gst_iterator_resync (iter);
624  if (ires == GST_ITERATOR_OK) {
630  active_sinkpad = sel->active_sinkpad = g_value_dup_object (&item);
631  g_value_reset (&item);
632  GST_DEBUG_OBJECT (sel, "Activating pad %s:%s",
633  GST_DEBUG_PAD_NAME (active_sinkpad));
634  } else
635  GST_WARNING_OBJECT (sel, "Couldn't find a default sink pad");
636  gst_iterator_free (iter);
637  }
638 
639  return active_sinkpad;
640 }
641 
645 static GstPad *
646 gst_join_request_new_pad (GstElement * element, GstPadTemplate * templ,
647  const gchar * unused, const GstCaps * caps)
648 {
649  GstJoin *sel;
650  gchar *name = NULL;
651  GstPad *sinkpad = NULL;
652  (void) unused;
653  (void) caps;
654 
655  g_return_val_if_fail (templ->direction == GST_PAD_SINK, NULL);
656 
657  sel = GST_JOIN (element);
658 
659  GST_JOIN_LOCK (sel);
660 
661  GST_LOG_OBJECT (sel, "Creating new pad sink_%u", sel->padcount);
662  name = g_strdup_printf ("sink_%u", sel->padcount++);
663  sinkpad = g_object_new (GST_TYPE_JOIN_PAD,
664  "name", name, "direction", templ->direction, "template", templ, NULL);
665  g_free (name);
666 
667  sel->n_pads++;
668 
669  gst_pad_set_event_function (sinkpad, GST_DEBUG_FUNCPTR (gst_join_pad_event));
670  gst_pad_set_query_function (sinkpad, GST_DEBUG_FUNCPTR (gst_join_pad_query));
671  gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_join_pad_chain));
672  gst_pad_set_iterate_internal_links_function (sinkpad,
673  GST_DEBUG_FUNCPTR (gst_join_pad_iterate_linked_pads));
674 
675  GST_OBJECT_FLAG_SET (sinkpad, GST_PAD_FLAG_PROXY_CAPS);
676  GST_OBJECT_FLAG_SET (sinkpad, GST_PAD_FLAG_PROXY_ALLOCATION);
677  gst_pad_set_active (sinkpad, TRUE);
678  gst_element_add_pad (GST_ELEMENT (sel), sinkpad);
679  GST_JOIN_UNLOCK (sel);
680 
681  return sinkpad;
682 }
683 
687 static gboolean
688 plugin_init (GstPlugin * plugin)
689 {
690  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "join", 0,
691  "gstreamer join element");
692 
693  if (!gst_element_register (plugin, "join", GST_RANK_NONE, GST_TYPE_JOIN)) {
694  return FALSE;
695  }
696 
697  return TRUE;
698 }
699 
700 #ifndef PACKAGE
701 #define PACKAGE "join"
702 #endif
703 
704 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
705  GST_VERSION_MINOR,
706  join,
707  "Select the out that arrived first among the input streams",
708  plugin_init, VERSION, "LGPL", PACKAGE,
709  "https://github.com/nnstreamer/nnstreamer")
forward_sticky_events
static gboolean forward_sticky_events(GstPad *sinkpad, GstEvent **event, gpointer user_data)
forward sticky event
Definition: gstjoin.c:198
PROP_ACTIVE_PAD
@ PROP_ACTIVE_PAD
Definition: gstjoin.c:66
gst_join_get_property
static void gst_join_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Getter for join properties.
Definition: gstjoin.c:565
GST_JOIN_PAD
#define GST_JOIN_PAD(obj)
Definition: gstjoin.c:76
FALSE
return FALSE
Definition: gsttensor_transform.c:590
_GstJoin::padcount
guint padcount
Definition: gstjoin.h:44
gst_join_get_linked_pad
static GstPad * gst_join_get_linked_pad(GstJoin *sel, GstPad *pad, gboolean strict)
Get linked pad.
Definition: gstjoin.c:591
gst_join_src_factory
static GstStaticPadTemplate gst_join_src_factory
The capabilities of the outputs.
Definition: gstjoin.c:56
GST_JOIN_LOCK
#define GST_JOIN_LOCK(sel)
Definition: gstjoin.c:39
GST_JOIN_UNLOCK
#define GST_JOIN_UNLOCK(sel)
Definition: gstjoin.c:40
_GstJoinPad
GstJoinPad data structure.
Definition: gstjoin.c:93
gst_join_init
static void gst_join_init(GstJoin *sel)
initialize the join element
Definition: gstjoin.c:474
gst_join_pad_event
static gboolean gst_join_pad_event(GstPad *pad, GstObject *parent, GstEvent *event)
event function for sink pad
Definition: gstjoin.c:233
PROP_0
@ PROP_0
Definition: gstjoin.c:64
gst_join_pad_get_type
GType gst_join_pad_get_type(void)
gst_join_pad_init
static void gst_join_pad_init(GstJoinPad *pad)
initialize the join pad
Definition: gstjoin.c:142
gst_join_pad_query
static gboolean gst_join_pad_query(GstPad *pad, GstObject *parent, GstQuery *query)
handlesink sink pad query
Definition: gstjoin.c:307
GST_JOIN_PAD_CAST
#define GST_JOIN_PAD_CAST(obj)
Definition: gstjoin.c:84
g_free
g_free(self->option[(opnum) - 1])
opnum: \
gst_join_set_active_pad
static gboolean gst_join_set_active_pad(GstJoin *self, GstPad *pad)
set active sink pad.
Definition: gstjoin.c:525
GST_IS_JOIN_PAD
#define GST_IS_JOIN_PAD(obj)
Definition: gstjoin.c:80
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(join_debug)
G_DEFINE_TYPE
G_DEFINE_TYPE(GstJoinPad, gst_join_pad, GST_TYPE_PAD)
G_DEFINE_TYPE_WITH_CODE
G_DEFINE_TYPE_WITH_CODE(GstJoin, gst_join, GST_TYPE_ELEMENT, GST_DEBUG_CATEGORY_INIT(join_debug, "join", 0, "An input stream join element"))
_GstJoinPad::segment
GstSegment segment
Definition: gstjoin.c:99
gst_join_pad_reset
static void gst_join_pad_reset(GstJoinPad *pad)
Clear and reset join pad.
Definition: gstjoin.c:161
plugin_init
static gboolean plugin_init(GstPlugin *plugin)
register this element
Definition: gstjoin.c:688
PACKAGE
#define PACKAGE
Definition: gstjoin.c:701
gst_join_sink_factory
static GstStaticPadTemplate gst_join_sink_factory
The capabilities of the inputs.
Definition: gstjoin.c:47
_GstJoinPad::group_id
guint group_id
Definition: gstjoin.c:97
gst_join_pad_iterate_linked_pads
static GstIterator * gst_join_pad_iterate_linked_pads(GstPad *pad, GstObject *parent)
strictly get the linked pad from the sinkpad.
Definition: gstjoin.c:173
_GstJoinPad::segment_seqnum
guint32 segment_seqnum
Definition: gstjoin.c:100
TRUE
return TRUE
Definition: gsttensor_if.c:897
gst_join_finalize
static void gst_join_finalize(GObject *object)
finalize join element.
Definition: gstjoin.c:509
_GstJoinClass
GstJoinClass inherits GstElementClass.
Definition: gstjoin.h:55
PROP_N_PADS
@ PROP_N_PADS
Definition: gstjoin.c:65
GST_TYPE_JOIN_PAD
#define GST_TYPE_JOIN_PAD
Definition: gstjoin.c:74
_GstJoin::n_pads
guint n_pads
Definition: gstjoin.h:43
GST_PLUGIN_DEFINE
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, nnstreamer, "NNStreamer plugin library allows neural networks in GStreamer pipelines. Use nnstreamer-check utility for more information of the current NNStreamer installation.", gst_nnstreamer_init, VERSION, "LGPL", "nnstreamer", "https://github.com/nnstreamer/nnstreamer")
gst_join_class_init
static void gst_join_class_init(GstJoinClass *klass)
initialize the join's class
Definition: gstjoin.c:437
_GstJoinPadClass::parent
GstPadClass parent
Definition: gstjoin.c:108
gst_join_dispose
static void gst_join_dispose(GObject *object)
dispose function for join element
Definition: gstjoin.c:494
GST_CAT_DEFAULT
#define GST_CAT_DEFAULT
Definition: gstjoin.c:35
_GstJoinPad::parent
GstPad parent
Definition: gstjoin.c:95
gst_join_get_active_sinkpad
static GstPad * gst_join_get_active_sinkpad(GstJoin *sel)
Get or create the active sinkpad.
Definition: gstjoin.c:612
gst_join_pad_class_init
static void gst_join_pad_class_init(GstJoinPadClass *klass)
initialize the join's pad class
Definition: gstjoin.c:129
_GstJoin::have_group_id
gboolean have_group_id
Definition: gstjoin.h:46
GST_TYPE_JOIN
#define GST_TYPE_JOIN
Definition: gstjoin.h:20
_GstJoin::active_sinkpad
GstPad * active_sinkpad
Definition: gstjoin.h:42
gst_join_request_new_pad
static GstPad * gst_join_request_new_pad(GstElement *element, GstPadTemplate *templ, const gchar *unused, const GstCaps *caps)
request new sink pad
Definition: gstjoin.c:646
_GstJoin::cond
GCond cond
Definition: gstjoin.h:49
gstjoin.h
Select the out that arrived first among the input streams.
_GstJoin
Internal data structure for join instances.
Definition: gstjoin.h:36
_GstJoin::srcpad
GstPad * srcpad
Definition: gstjoin.h:40
gst_join_pad_chain
static GstFlowReturn gst_join_pad_chain(GstPad *pad, GstObject *parent, GstBuffer *buf)
Chain function, this function does the actual processing.
Definition: gstjoin.c:357
_GstJoin::lock
GMutex lock
Definition: gstjoin.h:48
gst_join_pad_finalize
static void gst_join_pad_finalize(GObject *object)
finalize the join pad
Definition: gstjoin.c:151
GST_JOIN
#define GST_JOIN(obj)
Definition: gstjoin.h:22
_GstJoinPadClass
_GstJoinPadClass data structure
Definition: gstjoin.c:106