summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2016-04-02 11:37:10 +0100
committerTim-Philipp Müller <tim@centricular.com>2016-04-02 11:37:10 +0100
commitc33c6dea118726cd1ae769e315f43f033df382f6 (patch)
treebd6f4fe0b25c4f106748068963ea05239cddf4da
parent423ce62b82f3aa9e0975cc3dd509a8578c12d69f (diff)
plugin: port audio filter example to 1.0
https://bugzilla.gnome.org/show_bug.cgi?id=764409
-rw-r--r--gst-plugin/configure.ac1
-rw-r--r--gst-plugin/src/Makefile.am15
-rw-r--r--gst-plugin/src/gstaudiofilter.c255
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"
);