diff options
author | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2011-01-04 12:42:50 -0300 |
---|---|---|
committer | Tim-Philipp Müller <tim.muller@collabora.co.uk> | 2011-01-06 18:42:29 +0000 |
commit | 757dc90faa163a235e1d16791a0a0f8c74715768 (patch) | |
tree | 968a0c3c69602a2eb04aa2f5e7e8bb4a64aeb7b2 /plugins/elements/gstoutputselector.c | |
parent | c8ffd4e395261cdf6a88ac3ff13539fcc3add5cc (diff) |
output-selector: Add pad-negotiation-mode property
Adds getcaps/setcaps to output-selector and adds a property
to select which type of negotiation should be done.
The available modes are:
* none: no negotiation (current behavior), getcaps return ANY and
setcaps aren't set on any of the peers
* all: use all pads (default), getcaps returns the intersection of
peer pads and setcaps is set on all peers
* active: getcaps and setcaps are proxied to the active pad
https://bugzilla.gnome.org/show_bug.cgi?id=638381
Diffstat (limited to 'plugins/elements/gstoutputselector.c')
-rw-r--r-- | plugins/elements/gstoutputselector.c | 116 |
1 files changed, 109 insertions, 7 deletions
diff --git a/plugins/elements/gstoutputselector.c b/plugins/elements/gstoutputselector.c index c28ddb2e3..9d2fbfef8 100644 --- a/plugins/elements/gstoutputselector.c +++ b/plugins/elements/gstoutputselector.c @@ -49,13 +49,43 @@ GST_STATIC_PAD_TEMPLATE ("src%d", GST_PAD_REQUEST, GST_STATIC_CAPS_ANY); +enum GstOutputSelectorPadNegotiationMode +{ + GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_NONE, + GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL, + GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ACTIVE +}; +#define GST_TYPE_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE (gst_output_selector_pad_negotiation_mode_get_type()) +static GType +gst_output_selector_pad_negotiation_mode_get_type (void) +{ + static GType pad_negotiation_mode_type = 0; + static GEnumValue pad_negotiation_modes[] = { + {GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_NONE, "None", "none"}, + {GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL, "All", "all"}, + {GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ACTIVE, "Active", "active"}, + {0, NULL, NULL} + }; + + if (!pad_negotiation_mode_type) { + pad_negotiation_mode_type = + g_enum_register_static ("GstOutputSelectorPadNegotiationMode", + pad_negotiation_modes); + } + return pad_negotiation_mode_type; +} + + enum { PROP_0, PROP_ACTIVE_PAD, - PROP_RESEND_LATEST + PROP_RESEND_LATEST, + PROP_PAD_NEGOTIATION_MODE }; +#define DEFAULT_PAD_NEGOTIATION_MODE GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL + #define _do_init(bla) \ GST_DEBUG_CATEGORY_INIT (output_selector_debug, \ "output-selector", 0, "Output stream selector"); @@ -79,6 +109,8 @@ static GstStateChangeReturn gst_output_selector_change_state (GstElement * element, GstStateChange transition); static gboolean gst_output_selector_handle_sink_event (GstPad * pad, GstEvent * event); +static void gst_output_selector_switch_pad_negotiation_mode (GstOutputSelector * + sel, gint mode); static void gst_output_selector_base_init (gpointer g_class) @@ -113,6 +145,12 @@ gst_output_selector_class_init (GstOutputSelectorClass * klass) g_param_spec_boolean ("resend-latest", "Resend latest buffer", "Resend latest buffer after a switch to a new pad", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_PAD_NEGOTIATION_MODE, + g_param_spec_enum ("pad-negotiation-mode", "Pad negotiation mode", + "The mode to be used for pad negotiation", + GST_TYPE_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE, + DEFAULT_PAD_NEGOTIATION_MODE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_output_selector_request_new_pad); @@ -135,12 +173,6 @@ gst_output_selector_init (GstOutputSelector * sel, GST_DEBUG_FUNCPTR (gst_output_selector_handle_sink_event)); gst_pad_set_bufferalloc_function (sel->sinkpad, GST_DEBUG_FUNCPTR (gst_output_selector_buffer_alloc)); - /* - gst_pad_set_setcaps_function (sel->sinkpad, - GST_DEBUG_FUNCPTR (gst_pad_proxy_setcaps)); - gst_pad_set_getcaps_function (sel->sinkpad, - GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); - */ gst_element_add_pad (GST_ELEMENT (sel), sel->sinkpad); @@ -152,6 +184,8 @@ gst_output_selector_init (GstOutputSelector * sel, sel->resend_latest = FALSE; sel->latest_buffer = NULL; + gst_output_selector_switch_pad_negotiation_mode (sel, + DEFAULT_PAD_NEGOTIATION_MODE); } static void @@ -218,6 +252,11 @@ gst_output_selector_set_property (GObject * object, guint prop_id, sel->resend_latest = g_value_get_boolean (value); break; } + case PROP_PAD_NEGOTIATION_MODE:{ + gst_output_selector_switch_pad_negotiation_mode (sel, + g_value_get_enum (value)); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -243,12 +282,75 @@ gst_output_selector_get_property (GObject * object, guint prop_id, GST_OBJECT_UNLOCK (object); break; } + case PROP_PAD_NEGOTIATION_MODE: + g_value_set_enum (value, sel->pad_negotiation_mode); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } +static GstCaps * +gst_output_selector_sink_getcaps (GstPad * pad) +{ + GstOutputSelector *sel = GST_OUTPUT_SELECTOR (GST_PAD_PARENT (pad)); + GstPad *active; + GstCaps *caps; + + GST_OBJECT_LOCK (sel); + if (sel->pending_srcpad) + active = gst_object_ref (sel->pending_srcpad); + else + active = gst_object_ref (sel->active_srcpad); + GST_OBJECT_UNLOCK (sel); + + caps = gst_pad_peer_get_caps_reffed (active); + gst_object_unref (active); + if (caps == NULL) { + caps = gst_caps_new_any (); + } + return caps; +} + +static gboolean +gst_output_selector_sink_setcaps (GstPad * pad, GstCaps * caps) +{ + GstOutputSelector *sel = GST_OUTPUT_SELECTOR (GST_PAD_PARENT (pad)); + GstPad *active; + gboolean ret; + + GST_OBJECT_LOCK (sel); + if (sel->pending_srcpad) + active = gst_object_ref (sel->pending_srcpad); + else + active = gst_object_ref (sel->active_srcpad); + GST_OBJECT_UNLOCK (sel); + + ret = gst_pad_set_caps (active, caps); + gst_object_unref (active); + return ret; +} + +static void +gst_output_selector_switch_pad_negotiation_mode (GstOutputSelector * sel, + gint mode) +{ + sel->pad_negotiation_mode = mode; + if (mode == GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL) { + gst_pad_set_getcaps_function (sel->sinkpad, gst_pad_proxy_getcaps); + gst_pad_set_setcaps_function (sel->sinkpad, gst_pad_proxy_setcaps); + } else if (mode == GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_NONE) { + gst_pad_set_getcaps_function (sel->sinkpad, NULL); + gst_pad_set_setcaps_function (sel->sinkpad, NULL); + } else { /* active */ + gst_pad_set_getcaps_function (sel->sinkpad, + gst_output_selector_sink_getcaps); + gst_pad_set_setcaps_function (sel->sinkpad, + gst_output_selector_sink_setcaps); + } +} + static GstFlowReturn gst_output_selector_buffer_alloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf) |