diff options
author | Tim-Philipp Müller <tim@centricular.com> | 2016-04-02 11:37:10 +0100 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2016-04-02 11:37:10 +0100 |
commit | c33c6dea118726cd1ae769e315f43f033df382f6 (patch) | |
tree | bd6f4fe0b25c4f106748068963ea05239cddf4da /gst-plugin | |
parent | 423ce62b82f3aa9e0975cc3dd509a8578c12d69f (diff) |
plugin: port audio filter example to 1.0
https://bugzilla.gnome.org/show_bug.cgi?id=764409
Diffstat (limited to 'gst-plugin')
-rw-r--r-- | gst-plugin/configure.ac | 1 | ||||
-rw-r--r-- | gst-plugin/src/Makefile.am | 15 | ||||
-rw-r--r-- | gst-plugin/src/gstaudiofilter.c | 255 |
3 files changed, 165 insertions, 106 deletions
diff --git a/gst-plugin/configure.ac b/gst-plugin/configure.ac index 1908b28..7f69f0a 100644 --- a/gst-plugin/configure.ac +++ b/gst-plugin/configure.ac @@ -46,6 +46,7 @@ PKG_CHECK_MODULES(GST, [ gstreamer-1.0 >= $GST_REQUIRED gstreamer-base-1.0 >= $GST_REQUIRED gstreamer-controller-1.0 >= $GST_REQUIRED + gstreamer-audio-1.0 >= $GST_REQUIRED ], [ AC_SUBST(GST_CFLAGS) AC_SUBST(GST_LIBS) diff --git a/gst-plugin/src/Makefile.am b/gst-plugin/src/Makefile.am index 8f2bc4b..9f778e5 100644 --- a/gst-plugin/src/Makefile.am +++ b/gst-plugin/src/Makefile.am @@ -3,7 +3,7 @@ ############################################################################## # TODO: change libgstplugin.la to something else, e.g. libmysomething.la # ############################################################################## -plugin_LTLIBRARIES = libgstplugin.la +plugin_LTLIBRARIES = libgstplugin.la libgstaudiofilterexample.la ############################################################################## # TODO: for the next set of variables, name the prefix if you named the .la, # @@ -13,6 +13,8 @@ plugin_LTLIBRARIES = libgstplugin.la # libmysomething_la_LDFLAGS # ############################################################################## +## Plugin 1 + # sources used to compile this plug-in libgstplugin_la_SOURCES = gstplugin.c gstplugin.h @@ -22,5 +24,16 @@ libgstplugin_la_LIBADD = $(GST_LIBS) libgstplugin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstplugin_la_LIBTOOLFLAGS = --tag=disable-static +## Plugin 2 (audio filter example) + +# sources used to compile this plug-in +libgstaudiofilterexample_la_SOURCES = gstaudiofilter.c + +# compiler and linker flags used to compile this plugin, set in configure.ac +libgstaudiofilterexample_la_CFLAGS = $(GST_CFLAGS) +libgstaudiofilterexample_la_LIBADD = $(GST_LIBS) +libgstaudiofilterexample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstaudiofilterexample_la_LIBTOOLFLAGS = --tag=disable-static + # headers we need but don't want installed noinst_HEADERS = gstplugin.h diff --git a/gst-plugin/src/gstaudiofilter.c b/gst-plugin/src/gstaudiofilter.c index 462b763..4102a44 100644 --- a/gst-plugin/src/gstaudiofilter.c +++ b/gst-plugin/src/gstaudiofilter.c @@ -1,5 +1,4 @@ -/* - * GStreamer +/* GStreamer audio filter example class * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> * Copyright (C) <2003> David Schleef <ds@schleef.org> * Copyright (C) YEAR AUTHOR_NAME AUTHOR_EMAIL @@ -65,31 +64,35 @@ #include <gst/audio/gstaudiofilter.h> #include <string.h> -GST_DEBUG_CATEGORY_STATIC (gst_plugin_template_debug); -#define GST_CAT_DEFAULT gst_plugin_template_debug - -typedef struct _GstPluginTemplate GstPluginTemplate; -typedef struct _GstPluginTemplateClass GstPluginTemplateClass; - -#define GST_TYPE_PLUGIN_TEMPLATE \ - (gst_plugin_template_get_type()) -#define GST_PLUGIN_TEMPLATE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLUGIN_TEMPLATE,GstPluginTemplate)) -#define GST_PLUGIN_TEMPLATE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLUGIN_TEMPLATE,GstPluginTemplateClass)) -#define GST_IS_PLUGIN_TEMPLATE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLUGIN_TEMPLATE)) -#define GST_IS_PLUGIN_TEMPLATE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLUGIN_TEMPLATE)) - -struct _GstPluginTemplate +GST_DEBUG_CATEGORY_STATIC (audiofiltertemplate_debug); +#define GST_CAT_DEFAULT audiofiltertemplate_debug + +typedef struct _GstAudioFilterTemplate GstAudioFilterTemplate; +typedef struct _GstAudioFilterTemplateClass GstAudioFilterTemplateClass; + +/* These are boilerplate cast macros and type check macros */ +#define GST_TYPE_AUDIO_FILTER_TEMPLATE \ + (gst_audio_filter_template_get_type()) +#define GST_AUDIO_FILTER_TEMPLATE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_FILTER_TEMPLATE,GstAudioFilterTemplate)) +#define GST_AUDIO_FILTER_TEMPLATE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_FILTER_TEMPLATE,GstAudioFilterTemplateClass)) +#define GST_IS_AUDIO_FILTER_TEMPLATE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_FILTER_TEMPLATE)) +#define GST_IS_AUDIO_FILTER_TEMPLATE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_FILTER_TEMPLATE)) + +struct _GstAudioFilterTemplate { GstAudioFilter audiofilter; + + /* here you can add additional per-instance + * data such as properties */ }; -struct _GstPluginTemplateClass +struct _GstAudioFilterTemplateClass { - GstAudioFilterClass parent_class; + GstAudioFilterClass audiofilter_class; }; @@ -105,60 +108,45 @@ enum /* FILL ME */ }; -/* debug category for fltering log messages - * - * FIXME:exchange the string 'Template plugin' with your description - */ -#define DEBUG_INIT(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_plugin_template_debug, "plugin", 0, "Template plugin"); - -GST_BOILERPLATE_FULL (GstPluginTemplate, gst_plugin_template, - GstAudioFilter, GST_TYPE_AUDIO_FILTER, DEBUG_INIT); +G_DEFINE_TYPE (GstAudioFilterTemplate, gst_audio_filter_template, + GST_TYPE_AUDIO_FILTER); -static void gst_plugin_template_set_property (GObject * object, +static void gst_audio_filter_template_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_plugin_template_get_property (GObject * object, +static void gst_audio_filter_template_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static gboolean gst_plugin_template_setup (GstAudioFilter * filter, - GstRingBufferSpec * spec); -static GstFlowReturn gst_plugin_template_filter (GstBaseTransform * bt, +static gboolean gst_audio_filter_template_setup (GstAudioFilter * filter, + const GstAudioInfo * info); +static GstFlowReturn gst_audio_filter_template_filter (GstBaseTransform * bt, GstBuffer * outbuf, GstBuffer * inbuf); static GstFlowReturn -gst_plugin_template_filter_inplace (GstBaseTransform * base_transform, +gst_audio_filter_template_filter_inplace (GstBaseTransform * base_transform, GstBuffer * buf); -#define ALLOWED_CAPS_STRING \ - GST_AUDIO_INT_STANDARD_PAD_TEMPLATE_CAPS - -/* GObject vmethod implementations */ - -static void -gst_plugin_template_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstAudioFilterClass *audiofilter_class = GST_AUDIO_FILTER_CLASS (klass); - GstCaps *caps; - - gst_element_class_set_details_simple (element_class, - "Plugin", - "Filter/Effect/Audio", - "FIXME:Filters audio", - "AUTHOR_NAME AUTHOR_EMAIL"); +#if 0 +/* This means we support signed 16-bit pcm and signed 32-bit pcm in native + * endianness */ +#define SUPPORTED_CAPS_STRING \ + GST_AUDIO_CAPS_MAKE("{ " GST_AUDIO_NE(S16) ", " GST_AUDIO_NE(S32) " }") +#endif - caps = gst_caps_from_string (ALLOWED_CAPS_STRING); - gst_audio_filter_class_add_pad_templates (audiofilter_class, caps); - gst_caps_unref (caps); -} +/* For simplicity only support 16-bit pcm in native endianness for starters */ +#define SUPPORTED_CAPS_STRING \ + GST_AUDIO_CAPS_MAKE(GST_AUDIO_NE(S16)) +/* GObject vmethod implementations */ static void -gst_plugin_template_class_init (GstPluginTemplateClass * klass) +gst_audio_filter_template_class_init (GstAudioFilterTemplateClass * klass) { GObjectClass *gobject_class; + GstElementClass *element_class; GstBaseTransformClass *btrans_class; GstAudioFilterClass *audio_filter_class; + GstCaps *caps; gobject_class = (GObjectClass *) klass; + element_class = (GstElementClass *) klass; btrans_class = (GstBaseTransformClass *) klass; audio_filter_class = (GstAudioFilterClass *) klass; @@ -169,32 +157,42 @@ gst_plugin_template_class_init (GstPluginTemplateClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); #endif - gobject_class->set_property = gst_plugin_template_set_property; - gobject_class->get_property = gst_plugin_template_get_property; + gobject_class->set_property = gst_audio_filter_template_set_property; + gobject_class->get_property = gst_audio_filter_template_get_property; - /* this function will be called whenever the format changes */ - audio_filter_class->setup = gst_plugin_template_setup; + /* this function will be called when the format is set before the + * first buffer comes in, and whenever the format changes */ + audio_filter_class->setup = gst_audio_filter_template_setup; /* here you set up functions to process data (either in place, or from * one input buffer to another output buffer); only one is required */ - btrans_class->transform = gst_plugin_template_filter; - btrans_class->transform_ip = gst_plugin_template_filter_inplace; + btrans_class->transform = gst_audio_filter_template_filter; + btrans_class->transform_ip = gst_audio_filter_template_filter_inplace; + /* Set some basic metadata about your new element */ + gst_element_class_set_details_simple (element_class, + "Audio Filter Template", /* FIXME: short name */ + "Filter/Effect/Audio", + "Filters audio", /* FIXME: short description*/ + "Name <mail@example.com>"); /* FIXME: author */ + + caps = gst_caps_from_string (SUPPORTED_CAPS_STRING); + gst_audio_filter_class_add_pad_templates (audio_filter_class, caps); + gst_caps_unref (caps); } static void -gst_plugin_template_init (GstPluginTemplate * plugin_template, - GstPluginTemplateClass * g_class) +gst_audio_filter_template_init (GstAudioFilterTemplate * filter) { - GST_DEBUG ("init"); - - /* do stuff if you need to */ + /* This function is called when a new filter object is created. You + * would typically do things like initialise properties to their + * default values here if needed. */ } static void -gst_plugin_template_set_property (GObject * object, guint prop_id, +gst_audio_filter_template_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - GstPluginTemplate *filter = GST_PLUGIN_TEMPLATE (object); + GstAudioFilterTemplate *filter = GST_AUDIO_FILTER_TEMPLATE (object); GST_OBJECT_LOCK (filter); switch (prop_id) { @@ -206,10 +204,10 @@ gst_plugin_template_set_property (GObject * object, guint prop_id, } static void -gst_plugin_template_get_property (GObject * object, guint prop_id, +gst_audio_filter_template_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - GstPluginTemplate *filter = GST_PLUGIN_TEMPLATE (object); + GstAudioFilterTemplate *filter = GST_AUDIO_FILTER_TEMPLATE (object); GST_OBJECT_LOCK (filter); switch (prop_id) { @@ -221,16 +219,29 @@ gst_plugin_template_get_property (GObject * object, guint prop_id, } static gboolean -gst_plugin_template_setup (GstAudioFilter * filter, - GstRingBufferSpec * spec) +gst_audio_filter_template_setup (GstAudioFilter * filter, + const GstAudioInfo * info) { - GstPluginTemplate *plugin_template; + GstAudioFilterTemplate *filter_template; + GstAudioFormat fmt; + gint chans, rate; + + filter_template = GST_AUDIO_FILTER_TEMPLATE (filter); + + rate = GST_AUDIO_INFO_RATE (info); + chans = GST_AUDIO_INFO_CHANNELS (info); + fmt = GST_AUDIO_INFO_FORMAT (info); - plugin_template = GST_PLUGIN_TEMPLATE (filter); + GST_INFO_OBJECT (filter_template, "format %d (%s), rate %d, %d channels", + fmt, GST_AUDIO_INFO_NAME (info), rate, chans); - /* if any setup needs to be done, do it here */ + /* if any setup needs to be done (like memory allocated), do it here */ - return TRUE; /* it's all good */ + /* The audio filter base class also saves the audio info in + * GST_AUDIO_FILTER_INFO(filter) so it's automatically available + * later from there as well */ + + return TRUE; } /* You may choose to implement either a copying filter or an @@ -240,45 +251,79 @@ gst_plugin_template_setup (GstAudioFilter * filter, * with a minimum of memory copies. */ static GstFlowReturn -gst_plugin_template_filter (GstBaseTransform * base_transform, +gst_audio_filter_template_filter (GstBaseTransform * base_transform, GstBuffer * inbuf, GstBuffer * outbuf) { - GstPluginTemplate *plugin_template; - GstAudioFilter *audiofilter; - - audiofilter = GST_AUDIO_FILTER (base_transform); - plugin_template = GST_PLUGIN_TEMPLATE (base_transform); - - /* FIXME: do something interesting here. This simply copies the source - * to the destination. */ - - memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf), - GST_BUFFER_SIZE (inbuf)); + GstAudioFilterTemplate *filter = GST_AUDIO_FILTER_TEMPLATE (base_transform); + GstMapInfo map_in; + GstMapInfo map_out; + + GST_LOG_OBJECT (filter, "transform buffer"); + + /* FIXME: do something interesting here. We simply copy the input data + * to the output buffer for now. */ + if (gst_buffer_map (inbuf, &map_in, GST_MAP_READ)) { + if (gst_buffer_map (outbuf, &map_out, GST_MAP_WRITE)) { + g_assert (map_out.size == map_in.size); + memcpy (map_out.data, map_in.data, map_out.size); + gst_buffer_unmap (outbuf, &map_out); + } + gst_buffer_unmap (inbuf, &map_in); + } return GST_FLOW_OK; } static GstFlowReturn -gst_plugin_template_filter_inplace (GstBaseTransform * base_transform, +gst_audio_filter_template_filter_inplace (GstBaseTransform * base_transform, GstBuffer * buf) { - GstPluginTemplate *plugin_template; - GstAudioFilter *audiofilter; + GstAudioFilterTemplate *filter = GST_AUDIO_FILTER_TEMPLATE (base_transform); + GstFlowReturn flow = GST_FLOW_OK; + GstMapInfo map; - audiofilter = GST_AUDIO_FILTER (base_transform); - plugin_template = GST_PLUGIN_TEMPLATE (base_transform); + GST_LOG_OBJECT (filter, "transform buffer in place"); - /* FIXME: do something interesting here. This simply copies the source - * to the destination. */ + /* FIXME: do something interesting here. Doing nothing means the input + * buffer is simply pushed out as is without any modification */ + if (gst_buffer_map (buf, &map, GST_MAP_READWRITE)) { +#if 0 + switch (GST_AUDIO_FILTER_FORMAT (filter)) { + case GST_AUDIO_FORMAT_S16LE: + case GST_AUDIO_FORMAT_S16BE: { + gint16 *samples = map.data; + guint n_samples = map.size / sizeof (gint16); + guint i; + + for (i = 0; i < n; ++n) { + samples[i] = samples[i]; + } + break; + } + default: + g_warning ("Unexpected audio format %s!", + GST_AUDIO_INFO_NAME (GST_AUDIO_FILTER_INFO(filter))); + flow = GST_FLOW_ERROR; + break; + } +#endif + gst_buffer_unmap (buf, &map); + } - return GST_FLOW_OK; + return flow; } static gboolean plugin_init (GstPlugin * plugin) { - return gst_element_register (plugin, "plugin", GST_RANK_NONE, - GST_TYPE_PLUGIN_TEMPLATE); + /* Register debug category for filtering log messages + * FIXME:exchange the string 'Template plugin' with your description */ + GST_DEBUG_CATEGORY_INIT (audiofiltertemplate_debug, "audiofiltertemplate", 0, + "Audio filter template example"); + + /* This is the name used in gst-launch-1.0 and gst_element_factory_make() */ + return gst_element_register (plugin, "audiofiltertemplate", GST_RANK_NONE, + GST_TYPE_AUDIO_FILTER_TEMPLATE); } /* gstreamer looks for this structure to register plugins @@ -288,10 +333,10 @@ plugin_init (GstPlugin * plugin) GST_PLUGIN_DEFINE ( GST_VERSION_MAJOR, GST_VERSION_MINOR, - "plugin", - "Template plugin", + audiofiltertemplateplugin, + "Audio filter template plugin", plugin_init, VERSION, "LGPL", "GStreamer", - "http://gstreamer.net/" + "http://gstreamer.freedesktop.org" ); |