diff options
Diffstat (limited to 'gst')
31 files changed, 823 insertions, 90 deletions
diff --git a/gst/.gitignore b/gst/.gitignore index 08f5ed37d8..8e3b99e373 100644 --- a/gst/.gitignore +++ b/gst/.gitignore @@ -5,3 +5,4 @@ Makefile.in *.la .deps .libs +gstversion.h diff --git a/gst/Makefile.am b/gst/Makefile.am index f4f8aada27..1b4323c3f8 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -116,7 +116,8 @@ libgstinclude_HEADERS = \ gsttypefind.h \ gstutils.h \ gstparse.h \ - gstxml.h + gstxml.h \ + gstversion.h noinst_HEADERS = \ gst_private.h \ @@ -130,6 +131,6 @@ noinst_HEADERS = \ CFLAGS = $(LIBGST_CFLAGS) LIBS = $(LIBGST_LIBS) -libgst_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION) +libgst_la_LDFLAGS = -version-info $(GST_LIBVERSION) EXTRA_DIST = ROADMAP diff --git a/gst/Makefile.am.future b/gst/Makefile.am.future index 8b7e666ced..c31bf57ff6 100644 --- a/gst/Makefile.am.future +++ b/gst/Makefile.am.future @@ -80,7 +80,8 @@ libgstinclude_HEADERS = \ gsttypefind.h \ gstutils.h \ gstparse.h \ - gstxml.h + gstxml.h \ + gstversion.h noinst_HEADERS = \ gst_private.h \ @@ -92,7 +93,7 @@ noinst_HEADERS = \ gstsparc.h \ gstpropsprivate.h -libgst_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION) $(LIBGST_LIBS) +libgst_la_LDFLAGS = -version-info $(GST_LIBVERSION) $(LIBGST_LIBS) libgst_la_LIBADD = libcothreads.la EXTRA_DIST = ROADMAP diff --git a/gst/autoplug/Makefile.am b/gst/autoplug/Makefile.am index 0ddb2a8a74..8050727ae1 100644 --- a/gst/autoplug/Makefile.am +++ b/gst/autoplug/Makefile.am @@ -8,5 +8,5 @@ libgststaticautoplug_la_SOURCES = \ libgststaticautoplugrender_la_SOURCES = \ gststaticautoplugrender.c -libgststaticautoplug_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION) -libgststaticautoplugrender_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION) +libgststaticautoplug_la_LDFLAGS = -version-info $(GST_LIBVERSION) +libgststaticautoplugrender_la_LDFLAGS = -version-info $(GST_LIBVERSION) diff --git a/gst/autoplug/gststaticautoplug.c b/gst/autoplug/gststaticautoplug.c index ca06fe9398..11403a069d 100644 --- a/gst/autoplug/gststaticautoplug.c +++ b/gst/autoplug/gststaticautoplug.c @@ -80,15 +80,11 @@ gst_static_autoplug_class_init(GstStaticAutoplugClass *klass) static void gst_static_autoplug_init(GstStaticAutoplug *autoplug) { } -GstPlugin* -plugin_init (GModule *module) +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) { - GstPlugin *plugin; GstAutoplugFactory *factory; - plugin = gst_plugin_new("gststaticautoplug"); - g_return_val_if_fail(plugin != NULL,NULL); - gst_plugin_set_longname (plugin, "A static autoplugger"); factory = gst_autoplugfactory_new ("static", @@ -98,9 +94,16 @@ plugin_init (GModule *module) if (factory != NULL) { gst_plugin_add_autoplugger (plugin, factory); } - return plugin; + return TRUE; } +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "gststaticautoplug", + plugin_init +}; + static gboolean gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest) { diff --git a/gst/autoplug/gststaticautoplugrender.c b/gst/autoplug/gststaticautoplugrender.c index ec30e374a2..c544f7f189 100644 --- a/gst/autoplug/gststaticautoplugrender.c +++ b/gst/autoplug/gststaticautoplugrender.c @@ -80,15 +80,11 @@ gst_static_autoplug_render_class_init(GstStaticAutoplugRenderClass *klass) static void gst_static_autoplug_render_init(GstStaticAutoplugRender *autoplug) { } -GstPlugin* -plugin_init (GModule *module) +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) { - GstPlugin *plugin; GstAutoplugFactory *factory; - plugin = gst_plugin_new("gststaticautoplugrender"); - g_return_val_if_fail(plugin != NULL,NULL); - gst_plugin_set_longname (plugin, "A static autoplugger"); factory = gst_autoplugfactory_new ("staticrender", @@ -98,9 +94,16 @@ plugin_init (GModule *module) if (factory != NULL) { gst_plugin_add_autoplugger (plugin, factory); } - return plugin; + return TRUE; } +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "gststaticautoplugrender", + plugin_init +}; + static gboolean gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest) { @@ -267,7 +270,10 @@ gst_static_autoplug_to_render (GstAutoplug *autoplug, GstCaps *srccaps, GstEleme pad = GST_PAD_REALIZE (gst_element_get_pad_list (targetelement)->data); templ = GST_PAD_PADTEMPLATE (pad); - caps.sink = GST_PADTEMPLATE_CAPS (templ); + if (templ) + caps.sink = GST_PADTEMPLATE_CAPS (templ); + else + goto next; GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures"); @@ -283,7 +289,7 @@ gst_static_autoplug_to_render (GstAutoplug *autoplug, GstCaps *srccaps, GstEleme } else { } - +next: targetelement = va_arg (args, GstElement *); } diff --git a/gst/elements/Makefile.am b/gst/elements/Makefile.am index e41a972f40..e29530e069 100644 --- a/gst/elements/Makefile.am +++ b/gst/elements/Makefile.am @@ -15,6 +15,7 @@ libgstelements_la_SOURCES = \ gstidentity.c \ gstfakesink.c \ gstdisksrc.c \ + gstdisksink.c \ gstfdsrc.c \ gstfdsink.c \ gstmultidisksrc.c \ @@ -28,6 +29,7 @@ noinst_HEADERS = \ gstidentity.h \ gstfakesink.h \ gstdisksrc.h \ + gstdisksink.h \ gstfdsrc.h \ gstmultidisksrc.h \ gsthttpsrc.h \ @@ -39,4 +41,4 @@ noinst_HEADERS = \ CFLAGS += -O2 -Wall libgstelements_la_LIBADD = $(GHTTP_LIBS) -libgstelements_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION) +libgstelements_la_LDFLAGS = -version-info $(GST_LIBVERSION) diff --git a/gst/elements/gstdisksink.c b/gst/elements/gstdisksink.c new file mode 100644 index 0000000000..0861149107 --- /dev/null +++ b/gst/elements/gstdisksink.c @@ -0,0 +1,254 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000 Wim Taymans <wtay@chello.be> + * + * gstdisksink.c: + * + * 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. + */ + + +#include <gst/gst.h> +#include "gstdisksink.h" + + +GstElementDetails gst_disksink_details = { + "Disk Sink", + "Sink", + "Disk hole for data", + VERSION, + "Thomas <thomas@apestaart.org>", + "(C) 2001" +}; + + +/* DiskSink signals and args */ +enum { + /* FILL ME */ + SIGNAL_HANDOFF, + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_LOCATION, +}; + + +static void gst_disksink_class_init (GstDiskSinkClass *klass); +static void gst_disksink_init (GstDiskSink *disksink); + +static void gst_disksink_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksink_get_arg (GtkObject *object, GtkArg *arg, guint id); + +static gboolean gst_disksink_open_file (GstDiskSink *sink); +static void gst_disksink_close_file (GstDiskSink *sink); + +static void gst_disksink_chain (GstPad *pad,GstBuffer *buf); + +static GstElementStateReturn gst_disksink_change_state (GstElement *element); + +static GstElementClass *parent_class = NULL; +static guint gst_disksink_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gst_disksink_get_type (void) +{ + static GtkType disksink_type = 0; + + if (!disksink_type) { + static const GtkTypeInfo disksink_info = { + "GstDiskSink", + sizeof(GstDiskSink), + sizeof(GstDiskSinkClass), + (GtkClassInitFunc)gst_disksink_class_init, + (GtkObjectInitFunc)gst_disksink_init, + (GtkArgSetFunc)gst_disksink_set_arg, + (GtkArgGetFunc)gst_disksink_get_arg, + (GtkClassInitFunc)NULL, /* deprecated, do not use ! */ + }; + disksink_type = gtk_type_unique (GST_TYPE_ELEMENT, &disksink_info); + } + return disksink_type; +} + +static void +gst_disksink_class_init (GstDiskSinkClass *klass) +{ + GtkObjectClass *gtkobject_class; + GstElementClass *gstelement_class; + + gtkobject_class = (GtkObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = gtk_type_class (GST_TYPE_ELEMENT); + + gtk_object_add_arg_type ("GstDiskSink::location", GST_TYPE_FILENAME, + GTK_ARG_READWRITE, ARG_LOCATION); + + gst_disksink_signals[SIGNAL_HANDOFF] = + gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstDiskSinkClass, handoff), + gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (gtkobject_class, gst_disksink_signals, + LAST_SIGNAL); + + gtkobject_class->set_arg = gst_disksink_set_arg; + gtkobject_class->get_arg = gst_disksink_get_arg; + + gstelement_class->change_state = gst_disksink_change_state; +} + +static void +gst_disksink_init (GstDiskSink *disksink) +{ + GstPad *pad; + pad = gst_pad_new ("sink", GST_PAD_SINK); + gst_element_add_pad (GST_ELEMENT (disksink), pad); + gst_pad_set_chain_function (pad, gst_disksink_chain); + + disksink->filename = NULL; + disksink->file = NULL; +} + +static void +gst_disksink_set_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstDiskSink *sink; + + /* it's not null if we got it, but it might not be ours */ + sink = GST_DISKSINK (object); + + switch(id) { + case ARG_LOCATION: + if (sink->filename) + g_free (sink->filename); + sink->filename = g_strdup (GTK_VALUE_STRING (*arg)); + break; + default: + break; + } +} + +static void +gst_disksink_get_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstDiskSink *sink; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_DISKSINK (object)); + + sink = GST_DISKSINK (object); + + switch (id) { + case ARG_LOCATION: + GTK_VALUE_STRING (*arg) = sink->filename; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +static gboolean +gst_disksink_open_file (GstDiskSink *sink) +{ + g_return_val_if_fail (!GST_FLAG_IS_SET (sink, GST_DISKSINK_OPEN), FALSE); + + /* open the file */ + sink->file = fopen (sink->filename, "w"); + if (sink->file == NULL) { + perror ("open"); + gst_element_error (GST_ELEMENT (sink), g_strconcat("opening file \"", sink->filename, "\"", NULL)); + return FALSE; + } + + GST_FLAG_SET (sink, GST_DISKSINK_OPEN); + + return TRUE; +} + +static void +gst_disksink_close_file (GstDiskSink *sink) +{ + g_return_if_fail (GST_FLAG_IS_SET (sink, GST_DISKSINK_OPEN)); + + if (fclose (sink->file) != 0) + { + perror ("close"); + gst_element_error (GST_ELEMENT (sink), g_strconcat("closing file \"", sink->filename, "\"", NULL)); + } + else { + GST_FLAG_UNSET (sink, GST_DISKSINK_OPEN); + } +} + +/** + * gst_disksink_chain: + * @pad: the pad this disksink is connected to + * @buf: the buffer that has to be absorbed + * + * take the buffer from the pad and write to file if it's open + */ +static void +gst_disksink_chain (GstPad *pad, GstBuffer *buf) +{ + GstDiskSink *disksink; + guint16 bytes_written = 0; + + g_return_if_fail (pad != NULL); + g_return_if_fail (GST_IS_PAD (pad)); + g_return_if_fail (buf != NULL); + + disksink = GST_DISKSINK (gst_pad_get_parent (pad)); + + if (GST_FLAG_IS_SET (disksink, GST_DISKSINK_OPEN)) + { + bytes_written = fwrite (GST_BUFFER_DATA (buf), 1, GST_BUFFER_SIZE (buf), disksink->file); + if (bytes_written < GST_BUFFER_SIZE (buf)) + { + printf ("disksink : Warning : %d bytes should be written, only %d bytes written\n", + GST_BUFFER_SIZE (buf), bytes_written); + } + } + gst_buffer_unref (buf); + + gtk_signal_emit (GTK_OBJECT (disksink), gst_disksink_signals[SIGNAL_HANDOFF], + disksink); +} + +static GstElementStateReturn +gst_disksink_change_state (GstElement *element) +{ + g_return_val_if_fail (GST_IS_DISKSINK (element), GST_STATE_FAILURE); + + if (GST_STATE_PENDING (element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET (element, GST_DISKSINK_OPEN)) + gst_disksink_close_file (GST_DISKSINK (element)); + } else { + if (!GST_FLAG_IS_SET (element, GST_DISKSINK_OPEN)) { + if (!gst_disksink_open_file (GST_DISKSINK (element))) + return GST_STATE_FAILURE; + } + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; +} + diff --git a/gst/elements/gstdisksink.h b/gst/elements/gstdisksink.h new file mode 100644 index 0000000000..15f3d3213a --- /dev/null +++ b/gst/elements/gstdisksink.h @@ -0,0 +1,82 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000 Wim Taymans <wtay@chello.be> + * + * gstdisksink.h: + * + * 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_DISKSINK_H__ +#define __GST_DISKSINK_H__ + + +#include <config.h> +#include <gst/gst.h> + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +GstElementDetails gst_disksink_details; + + +#define GST_TYPE_DISKSINK \ + (gst_disksink_get_type()) +#define GST_DISKSINK(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_DISKSINK,GstDiskSink)) +#define GST_DISKSINK_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_DISKSINK,GstDiskSinkClass)) +#define GST_IS_DISKSINK(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_DISKSINK)) +#define GST_IS_DISKSINK_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSINK)) + +typedef struct _GstDiskSink GstDiskSink; +typedef struct _GstDiskSinkClass GstDiskSinkClass; + +typedef enum { + GST_DISKSINK_OPEN = GST_ELEMENT_FLAG_LAST, + + GST_DISKSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2, +} GstDiskSinkFlags; + +struct _GstDiskSink { + GstElement element; + + gchar *filename; + FILE *file; +}; + +struct _GstDiskSinkClass { + GstElementClass parent_class; + + /* signals */ + void (*handoff) (GstElement *element,GstPad *pad); +}; + +GtkType gst_disksink_get_type(void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_DISKSINK_H__ */ diff --git a/gst/elements/gstdisksrc.c b/gst/elements/gstdisksrc.c index 9e81eb9b73..72d454d510 100644 --- a/gst/elements/gstdisksrc.c +++ b/gst/elements/gstdisksrc.c @@ -312,8 +312,8 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l /* open the file and mmap it, necessary to go to READY state */ -static -gboolean gst_disksrc_open_file (GstDiskSrc *src) +static gboolean +gst_disksrc_open_file (GstDiskSrc *src) { g_return_val_if_fail (!GST_FLAG_IS_SET (src ,GST_DISKSRC_OPEN), FALSE); diff --git a/gst/elements/gstelements.c b/gst/elements/gstelements.c index 326d0e3aaf..afd0862126 100644 --- a/gst/elements/gstelements.c +++ b/gst/elements/gstelements.c @@ -24,6 +24,7 @@ #include <gst/gst.h> #include "gstdisksrc.h" +#include "gstdisksink.h" #include "gstidentity.h" #include "gstfakesink.h" #include "gstfakesrc.h" @@ -50,6 +51,7 @@ static struct _elements_entry _elements[] = { { "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details, NULL }, { "fakesink", gst_fakesink_get_type, &gst_fakesink_details, NULL }, { "disksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, + { "disksink", gst_disksink_get_type, &gst_disksink_details, NULL }, { "identity", gst_identity_get_type, &gst_identity_details, NULL }, { "fdsink", gst_fdsink_get_type, &gst_fdsink_details, NULL }, { "fdsrc", gst_fdsrc_get_type, &gst_fdsrc_details, NULL }, @@ -65,15 +67,12 @@ static struct _elements_entry _elements[] = { { NULL, 0 }, }; -GstPlugin *plugin_init (GModule *module) +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) { - GstPlugin *plugin; GstElementFactory *factory; gint i = 0; - plugin = gst_plugin_new("gstelements"); - g_return_val_if_fail(plugin != NULL,NULL); - gst_plugin_set_longname (plugin, "Standard GST Elements"); while (_elements[i].name) { @@ -92,5 +91,13 @@ GstPlugin *plugin_init (GModule *module) // INFO (GST_INFO_PLUGIN_LOAD,"gstelements: loaded %d standard elements", i); - return plugin; + return TRUE; } + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "gstelements", + plugin_init +}; + diff --git a/gst/elements/gstfakesink.c b/gst/elements/gstfakesink.c index 81709b764b..11590c4bab 100644 --- a/gst/elements/gstfakesink.c +++ b/gst/elements/gstfakesink.c @@ -44,6 +44,7 @@ enum { enum { ARG_0, ARG_NUM_SOURCES, + ARG_SILENT, }; @@ -90,6 +91,8 @@ gst_fakesink_class_init (GstFakeSinkClass *klass) gtk_object_add_arg_type ("GstFakeSink::num_sources", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_NUM_SOURCES); + gtk_object_add_arg_type ("GstFakeSink::silent", GTK_TYPE_BOOL, + GTK_ARG_READWRITE, ARG_SILENT); gst_fakesink_signals[SIGNAL_HANDOFF] = gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type, @@ -112,6 +115,7 @@ gst_fakesink_init (GstFakeSink *fakesink) gst_pad_set_chain_function (pad, gst_fakesink_chain); fakesink->sinkpads = g_slist_prepend (NULL, pad); fakesink->numsinkpads = 1; + fakesink->silent = FALSE; // we're ready right away, since we don't have any args... // gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_READY); @@ -138,6 +142,9 @@ gst_fakesink_set_arg (GtkObject *object, GtkArg *arg, guint id) sink->numsinkpads++; } break; + case ARG_SILENT: + sink->silent = GTK_VALUE_BOOL (*arg); + break; default: break; } @@ -157,6 +164,9 @@ gst_fakesink_get_arg (GtkObject *object, GtkArg *arg, guint id) case ARG_NUM_SOURCES: GTK_VALUE_INT (*arg) = sink->numsinkpads; break; + case ARG_SILENT: + GTK_VALUE_BOOL (*arg) = sink->silent; + break; default: arg->type = GTK_TYPE_INVALID; break; @@ -181,7 +191,8 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf) g_return_if_fail (buf != NULL); fakesink = GST_FAKESINK (gst_pad_get_parent (pad)); - g_print("fakesink: ******* (%s:%s)< \n",GST_DEBUG_PAD_NAME(pad)); + if (!fakesink->silent) + g_print("fakesink: ******* (%s:%s)< (%d bytes) \n",GST_DEBUG_PAD_NAME(pad),GST_BUFFER_SIZE(buf)); gst_buffer_unref (buf); diff --git a/gst/elements/gstfakesink.h b/gst/elements/gstfakesink.h index 74df38700d..573e8e512c 100644 --- a/gst/elements/gstfakesink.h +++ b/gst/elements/gstfakesink.h @@ -56,6 +56,7 @@ struct _GstFakeSink { GSList *sinkpads; gint numsinkpads; + gboolean silent; }; struct _GstFakeSinkClass { diff --git a/gst/elements/gstidentity.c b/gst/elements/gstidentity.c index a9126b671d..1e92dc5094 100644 --- a/gst/elements/gstidentity.c +++ b/gst/elements/gstidentity.c @@ -44,6 +44,7 @@ enum { ARG_0, ARG_LOOP_BASED, ARG_SLEEP_TIME, + ARG_SILENT, }; @@ -92,24 +93,59 @@ gst_identity_class_init (GstIdentityClass *klass) GTK_ARG_READWRITE, ARG_LOOP_BASED); gtk_object_add_arg_type ("GstIdentity::sleep_time", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_SLEEP_TIME); + gtk_object_add_arg_type ("GstIdentity::silent", GTK_TYPE_BOOL, + GTK_ARG_READWRITE, ARG_SILENT); gtkobject_class->set_arg = gst_identity_set_arg; gtkobject_class->get_arg = gst_identity_get_arg; } +static GstBufferPool* +gst_identity_get_bufferpool (GstPad *pad) +{ + GstIdentity *identity; + + identity = GST_IDENTITY (gst_pad_get_parent (pad)); + + return gst_pad_get_bufferpool (identity->srcpad); +} + +static GstPadNegotiateReturn +gst_identity_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstIdentity *identity; + + identity = GST_IDENTITY (gst_pad_get_parent (pad)); + + return gst_pad_negotiate_proxy (pad, identity->sinkpad, caps); +} + +static GstPadNegotiateReturn +gst_identity_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstIdentity *identity; + + identity = GST_IDENTITY (gst_pad_get_parent (pad)); + + return gst_pad_negotiate_proxy (pad, identity->srcpad, caps); +} + static void gst_identity_init (GstIdentity *identity) { identity->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); gst_element_add_pad (GST_ELEMENT (identity), identity->sinkpad); gst_pad_set_chain_function (identity->sinkpad, gst_identity_chain); + gst_pad_set_bufferpool_function (identity->sinkpad, gst_identity_get_bufferpool); + gst_pad_set_negotiate_function (identity->sinkpad, gst_identity_negotiate_sink); identity->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_element_add_pad (GST_ELEMENT (identity), identity->srcpad); + gst_pad_set_negotiate_function (identity->srcpad, gst_identity_negotiate_src); identity->loop_based = FALSE; -// identity->sleep_time = 10000; identity->sleep_time = 0; + identity->silent = FALSE; } static void @@ -122,7 +158,9 @@ gst_identity_chain (GstPad *pad, GstBuffer *buf) g_return_if_fail (buf != NULL); identity = GST_IDENTITY (gst_pad_get_parent (pad)); - g_print("identity: ******* (%s:%s)i \n",GST_DEBUG_PAD_NAME(pad)); + + if (!identity->silent) + g_print("identity: ******* (%s:%s)i \n",GST_DEBUG_PAD_NAME(pad)); gst_pad_push (identity->srcpad, buf); @@ -147,7 +185,8 @@ gst_identity_loop (GstElement *element) gst_pad_push (identity->srcpad, buf); - usleep (identity->sleep_time); + if (identity->sleep_time) + usleep (identity->sleep_time); } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element)); } @@ -177,6 +216,9 @@ gst_identity_set_arg (GtkObject *object, GtkArg *arg, guint id) case ARG_SLEEP_TIME: identity->sleep_time = GTK_VALUE_UINT (*arg); break; + case ARG_SILENT: + identity->silent = GTK_VALUE_BOOL (*arg); + break; default: break; } @@ -197,6 +239,9 @@ static void gst_identity_get_arg(GtkObject *object,GtkArg *arg,guint id) { case ARG_SLEEP_TIME: GTK_VALUE_UINT (*arg) = identity->sleep_time; break; + case ARG_SILENT: + GTK_VALUE_BOOL (*arg) = identity->silent; + break; default: arg->type = GTK_TYPE_INVALID; break; diff --git a/gst/elements/gstidentity.h b/gst/elements/gstidentity.h index 3c536484ec..129c4922a6 100644 --- a/gst/elements/gstidentity.h +++ b/gst/elements/gstidentity.h @@ -60,6 +60,7 @@ struct _GstIdentity { gboolean loop_based; guint sleep_time; + gboolean silent; }; struct _GstIdentityClass { @@ -26,8 +26,8 @@ #include <glib.h> +#include <gst/gstversion.h> #include <gst/gsttypes.h> - #include <gst/gstinfo.h> #include <gst/gstobject.h> #include <gst/gstpad.h> diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index 5f29ab84d1..23f68e73a0 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -33,8 +33,13 @@ static GMutex *_gst_buffer_chunk_lock; void _gst_buffer_initialize (void) { - _gst_buffer_chunk = g_mem_chunk_new ("GstBuffer", sizeof(GstBuffer), - sizeof(GstBuffer) * 16, G_ALLOC_AND_FREE); + int buffersize = sizeof(GstBuffer); + + // round up to the nearest 32 bytes for cache-line and other efficiencies + buffersize = ((buffersize-1 / 32) + 1) * 32; + + _gst_buffer_chunk = g_mem_chunk_new ("GstBuffer", buffersize, + buffersize * 32, G_ALLOC_AND_FREE); _gst_buffer_chunk_lock = g_mutex_new (); } @@ -56,7 +61,6 @@ gst_buffer_new(void) g_mutex_unlock (_gst_buffer_chunk_lock); GST_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer); -// g_print("allocating new mutex\n"); buffer->lock = g_mutex_new (); #ifdef HAVE_ATOMIC_H atomic_set (&buffer->refcount, 1); @@ -64,15 +68,16 @@ gst_buffer_new(void) buffer->refcount = 1; #endif buffer->flags = 0; - buffer->type = 0; buffer->data = NULL; buffer->size = 0; buffer->maxsize = 0; buffer->offset = 0; buffer->timestamp = 0; - buffer->metas = NULL; +// buffer->metas = NULL; buffer->parent = NULL; buffer->pool = NULL; + buffer->free = NULL; + buffer->copy = NULL; return buffer; } @@ -126,7 +131,6 @@ gst_buffer_create_sub (GstBuffer *parent, // copy flags and type from parent, for lack of better buffer->flags = parent->flags; - buffer->type = parent->type; // set the data pointer, size, offset, and maxsize buffer->data = parent->data + offset; @@ -136,9 +140,14 @@ gst_buffer_create_sub (GstBuffer *parent, // again, for lack of better, copy parent's timestamp buffer->timestamp = parent->timestamp; + buffer->maxage = parent->maxage; // no metas, this is sane I think - buffer->metas = NULL; +// buffer->metas = NULL; + + // if the parent buffer is a subbuffer itself, use its parent, a real buffer + if (parent->parent != NULL) + parent = parent->parent; // set parentage and reference the parent buffer->parent = parent; @@ -205,7 +214,7 @@ gst_buffer_append (GstBuffer *buffer, */ void gst_buffer_destroy (GstBuffer *buffer) { - GSList *metas; +// GSList *metas; g_return_if_fail (buffer != NULL); @@ -215,10 +224,15 @@ void gst_buffer_destroy (GstBuffer *buffer) if (GST_BUFFER_DATA (buffer) && !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE) && (buffer->parent == NULL)) { - g_free (GST_BUFFER_DATA (buffer)); -// g_print("freed data in buffer\n"); + // if there's a free function, use it + if (buffer->free != NULL) { + (buffer->free)(buffer); + } else { + g_free (GST_BUFFER_DATA (buffer)); + } } +/* DEPRACATED!!! // unreference any metadata attached to this buffer metas = buffer->metas; while (metas) { @@ -226,6 +240,7 @@ void gst_buffer_destroy (GstBuffer *buffer) metas = g_slist_next (metas); } g_slist_free (buffer->metas); +*/ // unreference the parent if there is one if (buffer->parent != NULL) @@ -334,7 +349,9 @@ gst_buffer_unref (GstBuffer *buffer) * @meta: the metadata to add to this buffer * * Add the meta data to the buffer. + * DEPRACATED!!! */ +/* DEPRACATED!!! void gst_buffer_add_meta (GstBuffer *buffer, GstMeta *meta) { @@ -344,15 +361,18 @@ gst_buffer_add_meta (GstBuffer *buffer, GstMeta *meta) gst_meta_ref (meta); buffer->metas = g_slist_append (buffer->metas,meta); } +*/ /** * gst_buffer_get_metas: * @buffer: the GstBuffer to get the metadata from * * Get the metadatas from the buffer. + * DEPRACATED!!! * * Returns: a GSList of metadata */ +/* DEPRACATED!!! GSList* gst_buffer_get_metas (GstBuffer *buffer) { @@ -360,15 +380,18 @@ gst_buffer_get_metas (GstBuffer *buffer) return buffer->metas; } +*/ /** * gst_buffer_get_first_meta: * @buffer: the GstBuffer to get the metadata from * * Get the first metadata from the buffer. + * DEPRACATED!!! * * Returns: the first metadata from the buffer */ +/* DEPRACATED!!! GstMeta* gst_buffer_get_first_meta (GstBuffer *buffer) { @@ -378,6 +401,7 @@ gst_buffer_get_first_meta (GstBuffer *buffer) return NULL; return GST_META (buffer->metas->data); } +*/ /** * gst_buffer_remove_meta: @@ -385,7 +409,9 @@ gst_buffer_get_first_meta (GstBuffer *buffer) * @meta: the metadata to remove * * Remove the given metadata from the buffer. + * DEPRACATED!!! */ +/* DEPRACATED!!! void gst_buffer_remove_meta (GstBuffer *buffer, GstMeta *meta) { @@ -395,3 +421,46 @@ gst_buffer_remove_meta (GstBuffer *buffer, GstMeta *meta) buffer->metas = g_slist_remove (buffer->metas, meta); gst_meta_unref (meta); } +*/ + + + +/** + * gst_buffer_copy: + * @buffer: the orignal GstBuffer to make a copy of + * + * Make a full copy of the give buffer, data and all. + * + * Returns: new buffer + */ +GstBuffer * +gst_buffer_copy (GstBuffer *buffer) +{ + GstBuffer *newbuf; + + // allocate a new buffer + newbuf = gst_buffer_new(); + + // if a copy function exists, use it, else copy the bytes + if (buffer->copy != NULL) { + (buffer->copy)(buffer,newbuf); + } else { + // copy the absolute size + newbuf->size = buffer->size; + // allocate space for the copy + newbuf->data = (guchar *)g_malloc (buffer->data); + // copy the data straight across + memcpy(newbuf,buffer->data,buffer->size); + // the new maxsize is the same as the size, since we just malloc'd it + newbuf->maxsize = newbuf->size; + } + newbuf->offset = buffer->offset; + newbuf->timestamp = buffer->timestamp; + newbuf->maxage = buffer->maxage; + + // since we just created a new buffer, so we have no ties to old stuff + newbuf->parent = NULL; + newbuf->pool = NULL; + + return newbuf; +} diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h index fe7e1fc782..375c27f182 100644 --- a/gst/gstbuffer.h +++ b/gst/gstbuffer.h @@ -25,7 +25,7 @@ #define __GST_BUFFER_H__ #include <gst/gstobject.h> -#include <gst/gstmeta.h> +//#include <gst/gstmeta.h> #ifdef HAVE_CONFIG_H #include "config.h" @@ -54,12 +54,15 @@ extern "C" { G_STMT_START{ (GST_BUFFER_FLAGS(buf) &= ~(1<<(flag))); }G_STMT_END -#define GST_BUFFER_TYPE(buf) (GST_BUFFER(buf)->type) #define GST_BUFFER_DATA(buf) (GST_BUFFER(buf)->data) #define GST_BUFFER_SIZE(buf) (GST_BUFFER(buf)->size) #define GST_BUFFER_OFFSET(buf) (GST_BUFFER(buf)->offset) #define GST_BUFFER_MAXSIZE(buf) (GST_BUFFER(buf)->maxsize) #define GST_BUFFER_TIMESTAMP(buf) (GST_BUFFER(buf)->timestamp) +#define GST_BUFFER_MAXAGE(buf) (GST_BUFFER(buf)->maxage) +#define GST_BUFFER_BUFFERPOOL(buf) (GST_BUFFER(buf)->pool) +#define GST_BUFFER_PARENT(buf) (GST_BUFFER(buf)->parent) +#define GST_BUFFER_POOL_PRIVATE(buf) (GST_BUFFER(buf)->pool_private) #define GST_BUFFER_LOCK(buf) (g_mutex_lock(GST_BUFFER(buf)->lock)) @@ -77,8 +80,14 @@ typedef enum { } GstBufferFlags; + typedef struct _GstBuffer GstBuffer; + +typedef void (*GstBufferFreeFunc) (GstBuffer *buf); +typedef void (*GstBufferCopyFunc) (GstBuffer *srcbuf,GstBuffer *dstbuf); + + #include <gst/gstbufferpool.h> struct _GstBuffer { @@ -94,8 +103,6 @@ struct _GstBuffer { #define GST_BUFFER_REFCOUNT(buf) (GST_BUFFER(buf)->refcount) #endif - /* data type of this buffer */ - guint16 type; /* flags */ guint16 flags; @@ -111,13 +118,18 @@ struct _GstBuffer { guint64 maxage; /* pointer to metadata, is really lame right now */ - GSList *metas; +// GSList *metas; /* subbuffer support, who's my parent? */ GstBuffer *parent; /* this is a pointer to the buffer pool (if any) */ GstBufferPool *pool; + gpointer pool_private; + + /* utility function pointers */ + GstBufferFreeFunc free; // free the data associated with the buffer + GstBufferCopyFunc copy; // copy the data from one buffer to another }; /* initialisation */ @@ -140,11 +152,16 @@ void gst_buffer_unref (GstBuffer *buffer); /* destroying the buffer */ void gst_buffer_destroy (GstBuffer *buffer); +/* copy buffer */ +GstBuffer* gst_buffer_copy (GstBuffer *buffer); + /* add, retrieve, and remove metadata from the buffer */ +/* DEPRACATED!!! void gst_buffer_add_meta (GstBuffer *buffer, GstMeta *meta); void gst_buffer_remove_meta (GstBuffer *buffer, GstMeta *meta); GstMeta* gst_buffer_get_first_meta (GstBuffer *buffer); GSList* gst_buffer_get_metas (GstBuffer *buffer); +*/ #ifdef __cplusplus } diff --git a/gst/gstcaps.c b/gst/gstcaps.c index c77d9bdafb..df122b58b2 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -119,26 +119,32 @@ gst_caps_destroy (GstCaps *caps) * * Decrease the refcount of this caps structure, * destroying it when the refcount is 0 + * + * Returns: caps or NULL if the refcount reached 0 */ -void +GstCaps* gst_caps_unref (GstCaps *caps) { gboolean zero; - GstCaps *next; + GstCaps **next; - g_return_if_fail (caps != NULL); + g_return_val_if_fail (caps != NULL, NULL); + g_return_val_if_fail (caps->refcount > 0, NULL); GST_CAPS_LOCK (caps); caps->refcount--; zero = (caps->refcount == 0); - next = caps->next; + next = &caps->next; GST_CAPS_UNLOCK (caps); - if (next) - gst_caps_unref (next); + if (*next) + *next = gst_caps_unref (*next); - if (zero) + if (zero) { gst_caps_destroy (caps); + caps = NULL; + } + return caps; } /** @@ -146,15 +152,19 @@ gst_caps_unref (GstCaps *caps) * @caps: the caps to ref * * Increase the refcount of this caps structure + * + * Returns: the caps with the refcount incremented */ -void +GstCaps* gst_caps_ref (GstCaps *caps) { - g_return_if_fail (caps != NULL); + g_return_val_if_fail (caps != NULL, NULL); GST_CAPS_LOCK (caps); caps->refcount++; GST_CAPS_UNLOCK (caps); + + return caps; } /** @@ -353,6 +363,36 @@ gst_caps_get_props (GstCaps *caps) } /** + * gst_caps_chain: + * @caps: a capabilty + * @...: more capabilities + * + * chains the given capabilities + * + * Returns: the new capability + */ +GstCaps* +gst_caps_chain (GstCaps *caps, ...) +{ + GstCaps *orig = caps; + va_list var_args; + + va_start (var_args, caps); + + while (caps) { + GstCaps *toadd; + + toadd = va_arg (var_args, GstCaps*); + gst_caps_append (caps, toadd); + + caps = toadd; + } + va_end (var_args); + + return orig; +} + +/** * gst_caps_append: * @caps: a capabilty * @capstoadd: the capability to append diff --git a/gst/gstcaps.h b/gst/gstcaps.h index c3c619ec9d..0f47c73b65 100644 --- a/gst/gstcaps.h +++ b/gst/gstcaps.h @@ -56,13 +56,35 @@ struct _GstCaps { GstCaps *next; }; +#define GST_CAPS_NEW(name, type, a...) \ +gst_caps_new ( \ + name, \ + type, \ + gst_props_new ( \ + a, \ + NULL)) + +#define GST_CAPS_FACTORY(factoryname, a...) \ +static GstCaps* \ +factoryname (void) \ +{ \ + static GstCaps *caps = NULL; \ + if (!caps) { \ + caps = gst_caps_chain (a, NULL); \ + } \ + return caps; \ +} + +#define GST_CAPS_GET(fact) (fact)() + + /* initialize the subsystem */ void _gst_caps_initialize (void); GstCaps* gst_caps_new (const gchar *name, const gchar *mime, GstProps *props); -void gst_caps_unref (GstCaps *caps); -void gst_caps_ref (GstCaps *caps); +GstCaps* gst_caps_unref (GstCaps *caps); +GstCaps* gst_caps_ref (GstCaps *caps); void gst_caps_destroy (GstCaps *caps); GstCaps* gst_caps_copy (GstCaps *caps); @@ -89,6 +111,7 @@ GstProps* gst_caps_get_props (GstCaps *caps); GstCaps* gst_caps_get_by_name (GstCaps *caps, const gchar *name); +GstCaps* gst_caps_chain (GstCaps *caps, ...); GstCaps* gst_caps_append (GstCaps *caps, GstCaps *capstoadd); GstCaps* gst_caps_prepend (GstCaps *caps, GstCaps *capstoadd); diff --git a/gst/gstobject.c b/gst/gstobject.c index e7fa7ce21d..589cf8f39d 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -363,6 +363,15 @@ gst_object_check_uniqueness (GList *list, const gchar *name) } +/** + * gst_object_save_thyself: + * @object: GstObject to save + * @parent: The parent XML node to save the object into + * + * Saves the given object into the parent XML node. + * + * Returns: the new xmlNodePtr with the saved object + */ xmlNodePtr gst_object_save_thyself (GstObject *object, xmlNodePtr parent) { @@ -546,6 +555,3 @@ gst_class_signal_emit_by_name (GstObject *object, gtk_signal_emit_by_name (oclass->signal_object, name, object, self); } - - - diff --git a/gst/gstpad.c b/gst/gstpad.c index 154e0e595c..abfdc39da4 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -186,6 +186,7 @@ gst_real_pad_init (GstRealPad *pad) pad->pullfunc = NULL; pad->pullregionfunc = NULL; + pad->bufferpoolfunc = NULL; pad->ghostpads = NULL; pad->caps = NULL; } @@ -460,7 +461,24 @@ gst_pad_set_newcaps_function (GstPad *pad, GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_NEWCAPSFUNC(pad),newcaps); } +/** + * gst_pad_set_bufferpool_function: + * @pad: the pad to set the bufferpool function for + * @bufpool: the bufferpool function + * + * Set the given bufferpool function for the pad. + */ +void +gst_pad_set_bufferpool_function (GstPad *pad, + GstPadBufferPoolFunction bufpool) +{ + g_return_if_fail (pad != NULL); + g_return_if_fail (GST_IS_REAL_PAD (pad)); + GST_RPAD_BUFFERPOOLFUNC (pad) = bufpool; + GST_DEBUG (0,"bufferpoolfunc for %s:%s(@%p) at %p is set to %p\n", + GST_DEBUG_PAD_NAME (pad), pad, &GST_RPAD_BUFFERPOOLFUNC (pad), bufpool); +} static void gst_pad_push_func(GstPad *pad, GstBuffer *buf) @@ -802,22 +820,29 @@ gboolean gst_pad_set_caps (GstPad *pad, GstCaps *caps) { + GstCaps *oldcaps; + g_return_val_if_fail (pad != NULL, FALSE); g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); // NOTE this restriction + GST_INFO (GST_CAT_CAPS, "setting caps %p on pad %s:%s", + caps, GST_DEBUG_PAD_NAME(pad)); + if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) { g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n", GST_DEBUG_PAD_NAME (pad)); //return FALSE; } - if (GST_PAD_CAPS (pad)) - gst_caps_unref (GST_PAD_CAPS (pad)); + oldcaps = GST_PAD_CAPS (pad); if (caps) gst_caps_ref (caps); GST_PAD_CAPS(pad) = caps; + if (oldcaps) + gst_caps_unref (oldcaps); + return gst_pad_renegotiate (pad); } @@ -938,6 +963,40 @@ gst_pad_get_peer (GstPad *pad) return GST_PAD(GST_PAD_PEER(pad)); } +/** + * gst_pad_get_bufferpool: + * @pad: the pad to get the bufferpool from + * + * Get the bufferpool of the peer pad of the given + * pad + * + * Returns: The GstBufferPool or NULL. + */ +GstBufferPool* +gst_pad_get_bufferpool (GstPad *pad) +{ + GstRealPad *peer; + + g_return_val_if_fail (pad != NULL, NULL); + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + peer = GST_RPAD_PEER(pad); + + g_return_val_if_fail (peer != NULL, NULL); + + GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad)); + + if (peer->bufferpoolfunc) { + GST_DEBUG (0,"calling bufferpoolfunc &%s (@%p) of peer pad %s:%s\n", + GST_DEBUG_FUNCPTR_NAME(peer->bufferpoolfunc),&peer->bufferpoolfunc,GST_DEBUG_PAD_NAME(((GstPad*)peer))); + return (peer->bufferpoolfunc)(((GstPad*)peer)); + } else { + GST_DEBUG (0,"no bufferpoolfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(((GstPad*)peer)),&peer->bufferpoolfunc); + return NULL; + } +} + + // FIXME this needs to be rethought soon static void gst_real_pad_destroy (GtkObject *object) @@ -1162,11 +1221,11 @@ gst_pad_renegotiate (GstPad *pad) GST_DEBUG (GST_CAT_NEGOTIATION, "pads aggreed on caps :)\n"); /* here we have some sort of aggreement of the caps */ - GST_PAD_CAPS (currentpad) = newcaps; + GST_PAD_CAPS (currentpad) = gst_caps_ref (newcaps); if (GST_RPAD_NEWCAPSFUNC (currentpad)) GST_RPAD_NEWCAPSFUNC (currentpad) (GST_PAD (currentpad), newcaps); - GST_PAD_CAPS (otherpad) = newcaps; + GST_PAD_CAPS (otherpad) = gst_caps_ref (newcaps); if (GST_RPAD_NEWCAPSFUNC (otherpad)) GST_RPAD_NEWCAPSFUNC (otherpad) (GST_PAD (otherpad), newcaps); } @@ -1444,11 +1503,12 @@ gst_padtemplate_init (GstPadTemplate *templ) } /** - * gst_padtemplate_create: + * gst_padtemplate_new: * @name_template: the name template * @direction: the direction for the template * @presence: the presence of the pad * @caps: a list of capabilities for the template + * @...: more capabilities * * Creates a new padtemplate from the given arguments. * diff --git a/gst/gstpad.h b/gst/gstpad.h index aa253112ba..9390d9960a 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -100,6 +100,7 @@ typedef GstBuffer* (*GstPadPullRegionFunction) (GstPad *pad, GstRegionType type typedef gboolean (*GstPadEOSFunction) (GstPad *pad); typedef GstPadNegotiateReturn (*GstPadNegotiateFunction) (GstPad *pad, GstCaps **caps, gpointer *data); typedef void (*GstPadNewCapsFunction) (GstPad *pad, GstCaps *caps); +typedef GstBufferPool* (*GstPadBufferPoolFunction) (GstPad *pad); typedef enum { GST_PAD_UNKNOWN, @@ -155,6 +156,7 @@ struct _GstRealPad { GstPadNegotiateFunction negotiatefunc; GstPadNewCapsFunction newcapsfunc; + GstPadBufferPoolFunction bufferpoolfunc; GList *ghostpads; }; @@ -205,6 +207,7 @@ struct _GstGhostPadClass { #define GST_RPAD_EOSFUNC(pad) (((GstRealPad *)(pad))->eosfunc) #define GST_RPAD_NEGOTIATEFUNC(pad) (((GstRealPad *)(pad))->negotiatefunc) #define GST_RPAD_NEWCAPSFUNC(pad) (((GstRealPad *)(pad))->newcapsfunc) +#define GST_RPAD_BUFFERPOOLFUNC(pad) (((GstRealPad *)(pad))->bufferpoolfunc) #define GST_RPAD_REGIONTYPE(pad) (((GstRealPad *)(pad))->regiontype) #define GST_RPAD_OFFSET(pad) (((GstRealPad *)(pad))->offset) @@ -258,6 +261,31 @@ struct _GstPadTemplateClass { void (*pad_created) (GstPadTemplate *templ, GstPad *pad); }; +#define GST_PADTEMPLATE_NEW(padname, dir, pres, a...) \ + gst_padtemplate_new ( \ + padname, \ + dir, \ + pres, \ + a , \ + NULL) + +#define GST_PADTEMPLATE_FACTORY(name, padname, dir, pres, a...) \ +static GstPadTemplate* \ +name (void) \ +{ \ + static GstPadTemplate *templ = NULL; \ + if (!templ) { \ + templ = GST_PADTEMPLATE_NEW ( \ + padname, \ + dir, \ + pres, \ + a ); \ + } \ + return templ; \ +} + +#define GST_PADTEMPLATE_GET(fact) (fact)() + GtkType gst_pad_get_type (void); GtkType gst_real_pad_get_type (void); @@ -276,6 +304,7 @@ void gst_pad_set_qos_function (GstPad *pad, GstPadQoSFunction qos); void gst_pad_set_eos_function (GstPad *pad, GstPadEOSFunction eos); void gst_pad_set_negotiate_function (GstPad *pad, GstPadNegotiateFunction nego); void gst_pad_set_newcaps_function (GstPad *pad, GstPadNewCapsFunction newcaps); +void gst_pad_set_bufferpool_function (GstPad *pad, GstPadBufferPoolFunction bufpool); gboolean gst_pad_set_caps (GstPad *pad, GstCaps *caps); GstCaps* gst_pad_get_caps (GstPad *pad); @@ -303,6 +332,8 @@ GstPadTemplate* gst_pad_get_padtemplate (GstPad *pad); GstPad* gst_pad_get_peer (GstPad *pad); +GstBufferPool* gst_pad_get_bufferpool (GstPad *pad); + gboolean gst_pad_connect (GstPad *srcpad, GstPad *sinkpad); void gst_pad_disconnect (GstPad *srcpad, GstPad *sinkpad); diff --git a/gst/gstplugin.c b/gst/gstplugin.c index 2e5362a2ae..fdbbd22b6c 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -27,6 +27,7 @@ #include "gst_private.h" #include "gstplugin.h" +#include "gstversion.h" #include "config.h" @@ -347,7 +348,7 @@ gboolean gst_plugin_load_absolute (const gchar *name) { GModule *module; - GstPluginInitFunc initfunc; + GstPluginDesc *desc; GstPlugin *plugin; struct stat file_status; @@ -363,10 +364,19 @@ gst_plugin_load_absolute (const gchar *name) module = g_module_open(name,G_MODULE_BIND_LAZY); if (module != NULL) { - if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) { - GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", - name); - if ((plugin = (initfunc)(module))) { + if (g_module_symbol(module,"plugin_desc",(gpointer *)&desc)) { + GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", name); + plugin = gst_plugin_new(desc->name, desc->major_version, desc->minor_version); + if (plugin != NULL) { + if (!((desc->plugin_init)(module, plugin))) { + GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" failed to initialise", + plugin->name); + g_free(plugin); + plugin = NULL; + } + } + + if (plugin != NULL) { GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded: %d elements, %d types", plugin->name,plugin->numelements,plugin->numtypes); plugin->filename = g_strdup(name); @@ -392,16 +402,23 @@ gst_plugin_load_absolute (const gchar *name) /** * gst_plugin_new: * @name: name of new plugin + * @major: major version number of core that plugin is compatible with + * @minor: minor version number of core that plugin is compatible with * * Create a new plugin with given name. * - * Returns: new plugin + * Returns: new plugin, or NULL if plugin couldn't be created, due to + * incompatible version number, or name already being allocated) */ GstPlugin* -gst_plugin_new (const gchar *name) +gst_plugin_new (const gchar *name, gint major, gint minor) { GstPlugin *plugin; + // return NULL if the major and minor version numbers are not compatible + // with ours. + if (major != GST_VERSION_MAJOR || minor != GST_VERSION_MINOR) return NULL; + // return NULL if the plugin is allready loaded plugin = gst_plugin_find (name); if (plugin) return NULL; diff --git a/gst/gstplugin.h b/gst/gstplugin.h index 299d10edc1..48b9c94669 100644 --- a/gst/gstplugin.h +++ b/gst/gstplugin.h @@ -40,7 +40,7 @@ typedef struct _GstPlugin GstPlugin; -typedef struct _GstPluginElement GstPluginElement; +typedef struct _GstPluginDesc GstPluginDesc; struct _GstPlugin { gchar *name; /* name of the plugin */ @@ -57,12 +57,19 @@ struct _GstPlugin { gboolean loaded; /* if the plugin is in memory */ }; +/* Initialiser function: returns TRUE if plugin initialised successfully */ +typedef gboolean (*GstPluginInitFunc) (GModule *module, GstPlugin *plugin); -typedef GstPlugin* (*GstPluginInitFunc) (GModule *module); +struct _GstPluginDesc { + gint major_version; /* major version of core that plugin was compiled for */ + gint minor_version; /* minor version of core that plugin was compiled for */ + gchar *name; /* name of plugin */ + GstPluginInitFunc plugin_init; /* pointer to plugin_init function */ +}; void _gst_plugin_initialize (void); -GstPlugin* gst_plugin_new (const gchar *name); +GstPlugin* gst_plugin_new (const gchar *name, gint major, gint minor); void gst_plugin_add_path (const gchar *path); diff --git a/gst/gstprops.h b/gst/gstprops.h index a67acf8aea..07cab144bc 100644 --- a/gst/gstprops.h +++ b/gst/gstprops.h @@ -51,6 +51,7 @@ typedef enum { } GstPropsId; #define GST_MAKE_FOURCC(a,b,c,d) ((a)|(b)<<8|(c)<<16|(d)<<24) +#define GST_STR_FOURCC(f) (((f)[0])|((f)[1]<<8)|((f)[2]<<16)|((f)[3]<<24)) #define GST_PROPS_LIST(a...) GST_PROPS_LIST_ID,##a,NULL #define GST_PROPS_INT(a) GST_PROPS_INT_ID,(a) diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 7e8c92e56a..258eb928ed 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -70,7 +70,8 @@ static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCa static GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data); static void gst_queue_chain (GstPad *pad, GstBuffer *buf); static GstBuffer * gst_queue_get (GstPad *pad); - +static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad); + static void gst_queue_flush (GstQueue *queue); static GstElementStateReturn gst_queue_change_state (GstElement *element); @@ -134,6 +135,7 @@ gst_queue_init (GstQueue *queue) gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad); gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos); gst_pad_set_negotiate_function (queue->sinkpad, gst_queue_handle_negotiate_sink); + gst_pad_set_bufferpool_function (queue->sinkpad, gst_queue_get_bufferpool); queue->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get)); @@ -152,6 +154,16 @@ gst_queue_init (GstQueue *queue) queue->fullcond = g_cond_new (); } +static GstBufferPool* +gst_queue_get_bufferpool (GstPad *pad) +{ + GstQueue *queue; + + queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + + return gst_pad_get_bufferpool (queue->srcpad); +} + static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) { diff --git a/gst/gstutils.c b/gst/gstutils.c index 2ade4a5053..3e4f6648d9 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -21,6 +21,7 @@ */ #include <stdio.h> +#include <string.h> #include "gstextratypes.h" @@ -254,7 +255,7 @@ gst_util_set_object_arg (GtkObject *object, guchar *name, gchar *value) } case GTK_TYPE_BOOL: { gboolean i = FALSE; - if (!strcmp ("true", value)) i = TRUE; + if (!strncmp ("true", value, 4)) i = TRUE; gtk_object_set (GTK_OBJECT (object), name, i, NULL); break; } diff --git a/gst/gstversion.h.in b/gst/gstversion.h.in new file mode 100644 index 0000000000..820e7fc7f7 --- /dev/null +++ b/gst/gstversion.h.in @@ -0,0 +1,31 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000 Wim Taymans <wtay@chello.be> + * + * gstversion.h: Version information for GStreamer + * + * 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_VERSION_H__ +#define __GST_VERSION_H__ + +#define GST_VERSION_MAJOR @GST_VERSION_MAJOR@ +#define GST_VERSION_MINOR @GST_VERSION_MINOR@ +#define GST_VERSION_MICRO @GST_VERSION_MICRO@ + +#endif /* __GST_H__ */ diff --git a/gst/types/Makefile.am b/gst/types/Makefile.am index ce8ad093d1..7de9743a3b 100644 --- a/gst/types/Makefile.am +++ b/gst/types/Makefile.am @@ -5,4 +5,4 @@ filter_LTLIBRARIES = libgsttypes.la libgsttypes_la_SOURCES = \ gsttypes.c -libgsttypes_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION) +libgsttypes_la_LDFLAGS = -version-info $(GST_LIBVERSION) diff --git a/gst/types/gsttypes.c b/gst/types/gsttypes.c index 9fe885b644..0723f3db00 100644 --- a/gst/types/gsttypes.c +++ b/gst/types/gsttypes.c @@ -28,15 +28,11 @@ GstTypeFactory _factories[] = { }; -GstPlugin* -plugin_init (GModule *module) +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) { - GstPlugin *plugin; gint i = 0; - plugin = gst_plugin_new ("gsttypes"); - g_return_val_if_fail (plugin != NULL,NULL); - while (_factories[i].mime) { gst_type_register (&_factories[i]); gst_plugin_add_type (plugin, &_factories[i]); @@ -46,5 +42,12 @@ plugin_init (GModule *module) //gst_info ("gsttypes: loaded %d standard types\n",i); - return plugin; + return TRUE; } + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "gsttypes", + plugin_init +}; |