From a12a55c9c5fe0ee7f693f573b72a15005061b523 Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Tue, 21 Apr 2009 04:08:59 +0000 Subject: Use gstvalve from binaries --- diff --git a/glive.py b/glive.py index f7d9966..2b59f7f 100644 --- a/glive.py +++ b/glive.py @@ -62,7 +62,7 @@ class Glive: self.play_pipe = gst.parse_launch( '%s ' \ - '! identity signal-handoffs=false silent=true name=valve ' \ + '! valve name=valve ' \ '! queue name=queue ' \ '! %s' \ % (self.src_str, self.play_str)) @@ -168,12 +168,12 @@ class Glive: def message_cb(bus, message, self): if message.type == gst.MESSAGE_APPLICATION \ and message.structure.get_name() == 'record.photo': - self.valve.props.drop_probability = 1 + self.valve.props.drop = True self.play_pipe.remove(self.photo) self.play_pipe.remove(self.photo_jpegenc) self.play_pipe.remove(self.photo_sink) self.valve.link(self.play_pipe.get_by_name('queue')) - self.valve.props.drop_probability = 0 + self.valve.props.drop = False self.after_photo_cb(self, message.structure['pixbuf']) bus = self.play_pipe.get_bus() @@ -186,13 +186,13 @@ class Glive: self.after_photo_cb = after_photo_cb and after_photo_cb or process_cb - self.valve.props.drop_probability = 1 + self.valve.props.drop = True self.valve.unlink(self.play_pipe.get_by_name('queue')) self.play_pipe.add(self.photo, self.photo_jpegenc, self.photo_sink) gst.element_link_many(self.valve, self.photo, self.photo_jpegenc, self.photo_sink) self.photo_sink.props.signal_handoffs = True - self.valve.props.drop_probability = 0 + self.valve.props.drop = False self._switch_pipe(self.play_pipe) diff --git a/gst/Makefile.am b/gst/Makefile.am index d9c25a4..31e0a31 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -1,4 +1,4 @@ -plugin_LTLIBRARIES = libgstvideorate.la +plugin_LTLIBRARIES = libgstvideorate.la libgstvalve.la libgstvideorate_la_SOURCES = gstvideorate.c gstvideorate.h libgstvideorate_la_CFLAGS = $(GST_CFLAGS) $(GST_AUDIO_CFLAGS) @@ -6,8 +6,15 @@ libgstvideorate_la_LIBADD = $(GST_LIBS) $(GST_AUDIO_LIBS) libgstvideorate_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstvideorate_la_LIBTOOLFLAGS = --tag=disable-static +libgstvalve_la_SOURCES = gstvalve.c gstvalve.h +libgstvalve_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(ERROR_CFLAGS) +libgstvalve_la_LIBADD = $(GST_LIBS_LIBS) +libgstvalve_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) +libgstvalve_la_LIBTOOLFLAGS = --tag=disable-static + ARCH = $(shell arch | grep 64 >/dev/null && echo linux64 || echo linux32) dist_xo: all + rm -rf $(ARCH) mkdir $(ARCH) - cp .libs/libgstvideorate.so $(ARCH)/ + cp .libs/libgst*.so $(ARCH)/ diff --git a/gst/gstvalve.c b/gst/gstvalve.c new file mode 100644 index 0000000..702b3e5 --- /dev/null +++ b/gst/gstvalve.c @@ -0,0 +1,311 @@ +/* + * Farsight Voice+Video library + * + * Copyright 2007 Collabora Ltd, + * Copyright 2007 Nokia Corporation + * @author: Olivier Crete + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ +/** + * SECTION:element-valve + * + * The valve is a simple element that drops buffers when the #GstValve::drop + * property is set to %TRUE and lets then through otherwise. + * + * Any downstream error received while the #GstValve::drop property is %FALSE + * is ignored. So downstream element can be set to %GST_STATE_NULL and removed, + * without using pad blocking. + * + * Last reviewed on 2008-02-10 (0.10.11) + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstvalve.h" + +#include + +GST_DEBUG_CATEGORY (valve_debug); +#define GST_CAT_DEFAULT (valve_debug) + +/* elementfactory information */ +static const GstElementDetails gst_valve_details = +GST_ELEMENT_DETAILS ("Valve element", + "Filter", + "This element drops all packets when drop is TRUE", + "Olivier Crete "); + + +static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + +/* Valve signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; + +enum +{ + ARG_0, + ARG_DROP, +}; + + + + +static void gst_valve_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_valve_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + +static gboolean gst_valve_event (GstPad * pad, GstEvent * event); +static GstFlowReturn gst_valve_buffer_alloc (GstPad * pad, guint64 offset, + guint size, GstCaps * caps, GstBuffer ** buf); +static GstFlowReturn gst_valve_chain (GstPad * pad, GstBuffer * buffer); +static GstCaps *gst_valve_getcaps (GstPad * pad); + +static void +_do_init (GType type) +{ + GST_DEBUG_CATEGORY_INIT (valve_debug, "valve", 0, "Valve"); +} + +GST_BOILERPLATE_FULL (GstValve, gst_valve, GstElement, + GST_TYPE_ELEMENT, _do_init); + +static void +gst_valve_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&srctemplate)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sinktemplate)); + + gst_element_class_set_details (element_class, &gst_valve_details); +} + +static void +gst_valve_class_init (GstValveClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_valve_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_valve_get_property); + + g_object_class_install_property (gobject_class, ARG_DROP, + g_param_spec_boolean ("drop", + "Drops all buffers if TRUE", + "If this property if TRUE, the element will drop all buffers, if its FALSE, it will let them through", + FALSE, G_PARAM_READWRITE)); + + parent_class = g_type_class_peek_parent (klass); +} + +static void +gst_valve_init (GstValve * valve, GstValveClass * klass) +{ + valve->drop = FALSE; + valve->discont = FALSE; + + valve->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); + gst_pad_set_getcaps_function (valve->srcpad, + GST_DEBUG_FUNCPTR (gst_valve_getcaps)); + gst_element_add_pad (GST_ELEMENT (valve), valve->srcpad); + + valve->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink"); + gst_pad_set_chain_function (valve->sinkpad, + GST_DEBUG_FUNCPTR (gst_valve_chain)); + gst_pad_set_event_function (valve->sinkpad, + GST_DEBUG_FUNCPTR (gst_valve_event)); + gst_pad_set_bufferalloc_function (valve->sinkpad, + GST_DEBUG_FUNCPTR (gst_valve_buffer_alloc)); + gst_pad_set_getcaps_function (valve->sinkpad, + GST_DEBUG_FUNCPTR (gst_valve_getcaps)); + gst_element_add_pad (GST_ELEMENT (valve), valve->sinkpad); +} + + +static void +gst_valve_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstValve *valve = GST_VALVE (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + case ARG_DROP: + GST_OBJECT_LOCK (object); + valve->drop = g_value_get_boolean (value); + GST_OBJECT_UNLOCK (object); + break; + } +} + +static void +gst_valve_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstValve *valve = GST_VALVE (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + case ARG_DROP: + GST_OBJECT_LOCK (object); + g_value_set_boolean (value, valve->drop); + GST_OBJECT_UNLOCK (object); + break; + } +} + +static GstFlowReturn +gst_valve_chain (GstPad * pad, GstBuffer * buffer) +{ + GstValve *valve = GST_VALVE (gst_pad_get_parent_element (pad)); + GstFlowReturn ret = GST_FLOW_OK; + gboolean drop; + + GST_OBJECT_LOCK (GST_OBJECT (valve)); + drop = valve->drop; + + if (!drop && valve->discont) { + buffer = gst_buffer_make_metadata_writable (buffer); + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); + valve->discont = FALSE; + } + GST_OBJECT_UNLOCK (GST_OBJECT (valve)); + + if (drop) + gst_buffer_unref (buffer); + else + ret = gst_pad_push (valve->srcpad, buffer); + + + GST_OBJECT_LOCK (GST_OBJECT (valve)); + if (valve->drop) + ret = GST_FLOW_OK; + GST_OBJECT_UNLOCK (GST_OBJECT (valve)); + + gst_object_unref (valve); + + return ret; +} + + +static gboolean +gst_valve_event (GstPad * pad, GstEvent * event) +{ + GstValve *valve = GST_VALVE (gst_pad_get_parent_element (pad)); + gboolean ret = TRUE; + gboolean drop; + + GST_OBJECT_LOCK (GST_OBJECT (valve)); + drop = valve->drop; + GST_OBJECT_UNLOCK (GST_OBJECT (valve)); + + if (drop) + gst_event_unref (event); + else + ret = gst_pad_push_event (valve->srcpad, event); + + GST_OBJECT_LOCK (GST_OBJECT (valve)); + if (valve->drop) + ret = TRUE; + GST_OBJECT_UNLOCK (GST_OBJECT (valve)); + + gst_object_unref (valve); + return ret; +} + +static GstFlowReturn +gst_valve_buffer_alloc (GstPad * pad, guint64 offset, guint size, + GstCaps * caps, GstBuffer ** buf) +{ + GstValve *valve = GST_VALVE (gst_pad_get_parent_element (pad)); + GstFlowReturn ret = GST_FLOW_OK; + gboolean drop; + + GST_OBJECT_LOCK (GST_OBJECT (valve)); + drop = valve->drop; + GST_OBJECT_UNLOCK (GST_OBJECT (valve)); + + if (drop) + *buf = NULL; + else + ret = gst_pad_alloc_buffer (valve->srcpad, offset, size, caps, buf); + + GST_OBJECT_LOCK (GST_OBJECT (valve)); + if (valve->drop) + ret = GST_FLOW_OK; + GST_OBJECT_UNLOCK (GST_OBJECT (valve)); + + gst_object_unref (valve); + + return ret; +} + +static GstCaps * +gst_valve_getcaps (GstPad * pad) +{ + GstValve *valve = GST_VALVE (gst_pad_get_parent (pad)); + GstCaps *caps; + + if (pad == valve->sinkpad) + caps = gst_pad_peer_get_caps (valve->srcpad); + else + caps = gst_pad_peer_get_caps (valve->sinkpad); + + if (caps == NULL) + caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); + + gst_object_unref (valve); + + return caps; +} + + +static gboolean +plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "valve", + GST_RANK_MARGINAL, GST_TYPE_VALVE); +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "valve", + "Valve", + plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/gst/gstvalve.h b/gst/gstvalve.h new file mode 100644 index 0000000..cc7cd38 --- /dev/null +++ b/gst/gstvalve.h @@ -0,0 +1,82 @@ +/* + * Farsight Voice+Video library + * + * Copyright 2007 Collabora Ltd, + * Copyright 2007 Nokia Corporation + * @author: Olivier Crete + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef __GST_VALVE_H__ +#define __GST_VALVE_H__ + +#include + +G_BEGIN_DECLS +/* #define's don't like whitespacey bits */ +#define GST_TYPE_VALVE \ + (gst_valve_get_type()) +#define GST_VALVE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + GST_TYPE_VALVE,GstValve)) +#define GST_VALVE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + GST_TYPE_VALVE,GstValveClass)) +#define GST_IS_VALVE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VALVE)) +#define GST_IS_VALVE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VALVE)) +typedef struct _GstValve GstValve; +typedef struct _GstValveClass GstValveClass; +typedef struct _GstValvePrivate GstValvePrivate; + +/** + * GstValve: + * + * The private valve structure + */ +struct _GstValve +{ + /*< private >*/ + GstElement parent; + + /* Protected by the object lock */ + gboolean drop; + + /* Protected by the stream lock */ + gboolean discont; + + GstPad *srcpad; + GstPad *sinkpad; + + /*< private > */ + gpointer _gst_reserved[GST_PADDING]; +}; + +struct _GstValveClass +{ + GstElementClass parent_class; + + /*< private > */ + gpointer _gst_reserved[GST_PADDING]; +}; + +GType gst_valve_get_type (void); + +G_END_DECLS +#endif /* __GST_VALVE_H__ */ -- cgit v0.9.1