summaryrefslogtreecommitdiffstats
path: root/gst/selector
diff options
context:
space:
mode:
Diffstat (limited to 'gst/selector')
-rw-r--r--gst/selector/gstinputselector.c72
-rw-r--r--gst/selector/gstinputselector.h3
-rw-r--r--gst/selector/gstoutputselector.c8
3 files changed, 74 insertions, 9 deletions
diff --git a/gst/selector/gstinputselector.c b/gst/selector/gstinputselector.c
index aef4bfc3..e66eed3d 100644
--- a/gst/selector/gstinputselector.c
+++ b/gst/selector/gstinputselector.c
@@ -65,7 +65,8 @@ GST_STATIC_PAD_TEMPLATE ("src",
enum
{
- PROP_ACTIVE_PAD = 1
+ PROP_ACTIVE_PAD = 1,
+ PROP_SELECT_ALL
};
enum
@@ -89,6 +90,7 @@ static GstPad *gst_input_selector_activate_sinkpad (GstInputSelector * sel,
static GstPad *gst_input_selector_get_linked_pad (GstPad * pad,
gboolean strict);
static void gst_input_selector_push_pending_stop (GstInputSelector * self);
+static gboolean gst_input_selector_check_eos (GstElement * selector);
#define GST_TYPE_SELECTOR_PAD \
(gst_selector_pad_get_type())
@@ -276,6 +278,11 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
/* only forward if we are dealing with the active sinkpad */
forward = gst_input_selector_is_active_sinkpad (sel, pad);
+ /* forward all events in select_all mode by default */
+ if (sel->select_all) {
+ forward = TRUE;
+ }
+
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_STOP:
gst_selector_pad_reset (selpad);
@@ -306,6 +313,10 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
}
case GST_EVENT_EOS:
selpad->eos = TRUE;
+ /* don't forward eos in select_all mode until all sink pads have eos */
+ if (sel->select_all && !gst_input_selector_check_eos (GST_ELEMENT (sel))) {
+ forward = FALSE;
+ }
break;
default:
break;
@@ -351,7 +362,7 @@ gst_selector_pad_bufferalloc (GstPad * pad, guint64 offset,
active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad);
/* Fallback allocation for buffers from pads except the selected one */
- if (pad != active_sinkpad) {
+ if (pad != active_sinkpad && !sel->select_all) {
GST_DEBUG_OBJECT (sel,
"Pad %s:%s is not selected. Performing fallback allocation",
GST_DEBUG_PAD_NAME (pad));
@@ -429,7 +440,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
}
/* Ignore buffers from pads except the selected one */
- if (pad != active_sinkpad)
+ if (pad != active_sinkpad && !sel->select_all)
goto ignore;
gst_input_selector_push_pending_stop (sel);
@@ -535,6 +546,9 @@ gst_input_selector_class_init (GstInputSelectorClass * klass)
g_object_class_install_property (gobject_class, PROP_ACTIVE_PAD,
g_param_spec_string ("active-pad", "Active pad",
"Name of the currently" " active sink pad", NULL, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_SELECT_ALL,
+ g_param_spec_boolean ("select-all", "Select all mode",
+ "Forwards data from all input pads", FALSE, G_PARAM_READWRITE));
gobject_class->dispose = gst_input_selector_dispose;
gstelement_class->request_new_pad = gst_input_selector_request_new_pad;
gstelement_class->release_pad = gst_input_selector_release_pad;
@@ -618,6 +632,8 @@ gst_input_selector_init (GstInputSelector * sel)
sel->blocked_cond = g_cond_new ();
sel->blocked = FALSE;
+
+ sel->select_all = FALSE;
}
static void
@@ -721,6 +737,9 @@ gst_input_selector_set_property (GObject * object, guint prop_id,
gst_input_selector_set_active_pad (sel,
g_value_get_string (value), GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE);
break;
+ case PROP_SELECT_ALL:
+ sel->select_all = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -744,6 +763,9 @@ gst_input_selector_get_property (GObject * object, guint prop_id,
GST_OBJECT_UNLOCK (object);
break;
}
+ case PROP_SELECT_ALL:
+ g_value_set_boolean (value, sel->select_all);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -776,8 +798,13 @@ gst_input_selector_getcaps (GstPad * pad)
GstObject *parent;
GstCaps *caps;
- otherpad = gst_input_selector_get_linked_pad (pad, FALSE);
parent = gst_object_get_parent (GST_OBJECT (pad));
+ if (GST_INPUT_SELECTOR (parent)->select_all) {
+ caps = gst_pad_proxy_getcaps (pad);
+ goto done;
+ }
+
+ otherpad = gst_input_selector_get_linked_pad (pad, FALSE);
if (!otherpad) {
GST_DEBUG_OBJECT (parent,
"Pad %s:%s not linked, returning ANY", GST_DEBUG_PAD_NAME (pad));
@@ -793,6 +820,7 @@ gst_input_selector_getcaps (GstPad * pad)
gst_object_unref (otherpad);
}
+done:
gst_object_unref (parent);
return caps;
}
@@ -981,3 +1009,39 @@ gst_input_selector_switch (GstInputSelector * self, const gchar * pad_name,
g_cond_broadcast (self->blocked_cond);
GST_OBJECT_UNLOCK (self);
}
+
+static gboolean
+gst_input_selector_check_eos (GstElement * selector)
+{
+ GstIterator *it = gst_element_iterate_sink_pads (selector);
+ GstIteratorResult ires;
+ gpointer item;
+ gboolean done = FALSE, is_eos = FALSE;
+ GstSelectorPad *pad;
+
+ while (!done) {
+ ires = gst_iterator_next (it, &item);
+ switch (ires) {
+ case GST_ITERATOR_DONE:
+ GST_INFO_OBJECT (selector, "all sink pads have eos");
+ done = TRUE;
+ is_eos = TRUE;
+ break;
+ case GST_ITERATOR_OK:
+ pad = GST_SELECTOR_PAD_CAST (item);
+ if (!pad->eos) {
+ done = TRUE;
+ }
+ break;
+ case GST_ITERATOR_RESYNC:
+ gst_iterator_resync (it);
+ break;
+ default:
+ done = TRUE;
+ break;
+ }
+ }
+ gst_iterator_free (it);
+
+ return is_eos;
+}
diff --git a/gst/selector/gstinputselector.h b/gst/selector/gstinputselector.h
index bb1a28db..ee683465 100644
--- a/gst/selector/gstinputselector.h
+++ b/gst/selector/gstinputselector.h
@@ -54,6 +54,9 @@ struct _GstInputSelector {
gboolean blocked;
gboolean pending_stop;
GstSegment pending_stop_segment;
+
+ /* select all mode, send data from all input pads forward */
+ gboolean select_all;
};
struct _GstInputSelectorClass {
diff --git a/gst/selector/gstoutputselector.c b/gst/selector/gstoutputselector.c
index a60df6a9..f8ed8846 100644
--- a/gst/selector/gstoutputselector.c
+++ b/gst/selector/gstoutputselector.c
@@ -367,11 +367,9 @@ gst_output_selector_chain (GstPad * pad, GstBuffer * buf)
}
/* Keep reference to latest buffer to resend it after switch */
- if (osel->resend_latest) {
- if (osel->latest_buffer)
- gst_buffer_unref (osel->latest_buffer);
- osel->latest_buffer = gst_buffer_ref (buf);
- }
+ if (osel->latest_buffer)
+ gst_buffer_unref (osel->latest_buffer);
+ osel->latest_buffer = gst_buffer_ref (buf);
/* Keep track of last stop and use it in NEWSEGMENT start after
switching to a new src pad */