2 * Farsight Voice+Video library
4 * Copyright 2007 Collabora Ltd,
5 * Copyright 2007 Nokia Corporation
6 * @author: Olivier Crete <olivier.crete@collabora.co.uk>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
25 * SECTION:element-valve
27 * The valve is a simple element that drops buffers when the #GstValve::drop
28 * property is set to %TRUE and lets then through otherwise.
30 * Any downstream error received while the #GstValve::drop property is %FALSE
31 * is ignored. So downstream element can be set to %GST_STATE_NULL and removed,
32 * without using pad blocking.
34 * Last reviewed on 2008-02-10 (0.10.11)
45 GST_DEBUG_CATEGORY (valve_debug);
46 #define GST_CAT_DEFAULT (valve_debug)
48 /* elementfactory information */
49 static const GstElementDetails gst_valve_details =
50 GST_ELEMENT_DETAILS ("Valve element",
52 "This element drops all packets when drop is TRUE",
53 "Olivier Crete <olivier.crete@collabora.co.uk>");
56 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
61 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
66 /* Valve signals and args */
82 static void gst_valve_set_property (GObject * object,
83 guint prop_id, const GValue * value, GParamSpec * pspec);
84 static void gst_valve_get_property (GObject * object,
85 guint prop_id, GValue * value, GParamSpec * pspec);
87 static gboolean gst_valve_event (GstPad * pad, GstEvent * event);
88 static GstFlowReturn gst_valve_buffer_alloc (GstPad * pad, guint64 offset,
89 guint size, GstCaps * caps, GstBuffer ** buf);
90 static GstFlowReturn gst_valve_chain (GstPad * pad, GstBuffer * buffer);
91 static GstCaps *gst_valve_getcaps (GstPad * pad);
96 GST_DEBUG_CATEGORY_INIT (valve_debug, "valve", 0, "Valve");
99 GST_BOILERPLATE_FULL (GstValve, gst_valve, GstElement,
100 GST_TYPE_ELEMENT, _do_init);
103 gst_valve_base_init (gpointer klass)
105 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
107 gst_element_class_add_pad_template (element_class,
108 gst_static_pad_template_get (&srctemplate));
109 gst_element_class_add_pad_template (element_class,
110 gst_static_pad_template_get (&sinktemplate));
112 gst_element_class_set_details (element_class, &gst_valve_details);
116 gst_valve_class_init (GstValveClass * klass)
118 GObjectClass *gobject_class;
120 gobject_class = (GObjectClass *) klass;
122 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_valve_set_property);
123 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_valve_get_property);
125 g_object_class_install_property (gobject_class, ARG_DROP,
126 g_param_spec_boolean ("drop",
127 "Drops all buffers if TRUE",
128 "If this property if TRUE, the element will drop all buffers, if its FALSE, it will let them through",
129 FALSE, G_PARAM_READWRITE));
131 parent_class = g_type_class_peek_parent (klass);
135 gst_valve_init (GstValve * valve, GstValveClass * klass)
138 valve->discont = FALSE;
140 valve->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
141 gst_pad_set_getcaps_function (valve->srcpad,
142 GST_DEBUG_FUNCPTR (gst_valve_getcaps));
143 gst_element_add_pad (GST_ELEMENT (valve), valve->srcpad);
145 valve->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
146 gst_pad_set_chain_function (valve->sinkpad,
147 GST_DEBUG_FUNCPTR (gst_valve_chain));
148 gst_pad_set_event_function (valve->sinkpad,
149 GST_DEBUG_FUNCPTR (gst_valve_event));
150 gst_pad_set_bufferalloc_function (valve->sinkpad,
151 GST_DEBUG_FUNCPTR (gst_valve_buffer_alloc));
152 gst_pad_set_getcaps_function (valve->sinkpad,
153 GST_DEBUG_FUNCPTR (gst_valve_getcaps));
154 gst_element_add_pad (GST_ELEMENT (valve), valve->sinkpad);
159 gst_valve_set_property (GObject * object,
160 guint prop_id, const GValue * value, GParamSpec * pspec)
162 GstValve *valve = GST_VALVE (object);
166 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
169 GST_OBJECT_LOCK (object);
170 valve->drop = g_value_get_boolean (value);
171 GST_OBJECT_UNLOCK (object);
177 gst_valve_get_property (GObject * object,
178 guint prop_id, GValue * value, GParamSpec * pspec)
180 GstValve *valve = GST_VALVE (object);
184 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
187 GST_OBJECT_LOCK (object);
188 g_value_set_boolean (value, valve->drop);
189 GST_OBJECT_UNLOCK (object);
195 gst_valve_chain (GstPad * pad, GstBuffer * buffer)
197 GstValve *valve = GST_VALVE (gst_pad_get_parent_element (pad));
198 GstFlowReturn ret = GST_FLOW_OK;
201 GST_OBJECT_LOCK (GST_OBJECT (valve));
204 if (!drop && valve->discont) {
205 buffer = gst_buffer_make_metadata_writable (buffer);
206 GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
207 valve->discont = FALSE;
209 GST_OBJECT_UNLOCK (GST_OBJECT (valve));
212 gst_buffer_unref (buffer);
214 ret = gst_pad_push (valve->srcpad, buffer);
217 GST_OBJECT_LOCK (GST_OBJECT (valve));
220 GST_OBJECT_UNLOCK (GST_OBJECT (valve));
222 gst_object_unref (valve);
229 gst_valve_event (GstPad * pad, GstEvent * event)
231 GstValve *valve = GST_VALVE (gst_pad_get_parent_element (pad));
235 GST_OBJECT_LOCK (GST_OBJECT (valve));
237 GST_OBJECT_UNLOCK (GST_OBJECT (valve));
240 gst_event_unref (event);
242 ret = gst_pad_push_event (valve->srcpad, event);
244 GST_OBJECT_LOCK (GST_OBJECT (valve));
247 GST_OBJECT_UNLOCK (GST_OBJECT (valve));
249 gst_object_unref (valve);
254 gst_valve_buffer_alloc (GstPad * pad, guint64 offset, guint size,
255 GstCaps * caps, GstBuffer ** buf)
257 GstValve *valve = GST_VALVE (gst_pad_get_parent_element (pad));
258 GstFlowReturn ret = GST_FLOW_OK;
261 GST_OBJECT_LOCK (GST_OBJECT (valve));
263 GST_OBJECT_UNLOCK (GST_OBJECT (valve));
268 ret = gst_pad_alloc_buffer (valve->srcpad, offset, size, caps, buf);
270 GST_OBJECT_LOCK (GST_OBJECT (valve));
273 GST_OBJECT_UNLOCK (GST_OBJECT (valve));
275 gst_object_unref (valve);
281 gst_valve_getcaps (GstPad * pad)
283 GstValve *valve = GST_VALVE (gst_pad_get_parent (pad));
286 if (pad == valve->sinkpad)
287 caps = gst_pad_peer_get_caps (valve->srcpad);
289 caps = gst_pad_peer_get_caps (valve->sinkpad);
292 caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
294 gst_object_unref (valve);
301 plugin_init (GstPlugin * plugin)
303 return gst_element_register (plugin, "valve",
304 GST_RANK_MARGINAL, GST_TYPE_VALVE);
307 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
311 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)