Commit 70e208d0 authored by Juan Manuel Borges Caño's avatar Juan Manuel Borges Caño Committed by Stefan Sauer
Browse files

ladspa: improved port to gstreamer 1.0

Fixes: #698927
parent f1a6d84a
......@@ -346,7 +346,7 @@ GST_PLUGINS_NONPORTED=" cdxaparse \
videomeasure videosignal vmnc \
linsys vcd \
apexsink cdaudio dc1394 dirac directfb \
gsettings ladspa \
gsettings \
musepack musicbrainz nas neon ofa openal sdl sndfile timidity \
directdraw direct3d9 acm wininet \
xvid lv2 teletextdec sndio osx_video quicktime"
......
plugin_LTLIBRARIES = libgstladspa.la
libgstladspa_la_SOURCES = gstladspa.c
libgstladspa_la_SOURCES = \
gstladspautils.c \
gstladspafilter.c \
gstladspasource.c \
gstladspasink.c \
gstladspa.c
libgstladspa_la_CFLAGS = \
-I$(top_srcdir)/gst-libs \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_CFLAGS) $(LRDF_CFLAGS)
$(GST_BASE_CFLAGS) \
$(GST_CFLAGS) \
$(LRDF_CFLAGS) \
$(GST_PLUGINS_BAD_CFLAGS)
libgstladspa_la_LIBADD = \
$(top_builddir)/gst-libs/gst/signalprocessor/libgstsignalprocessor-@GST_API_VERSION@.la \
$(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) \
$(LIBM) $(LRDF_LIBS)
$(GST_PLUGINS_BASE_LIBS) \
-lgstaudio-$(GST_API_VERSION) \
$(GST_BASE_LIBS) \
$(GST_LIBS) \
$(LIBM) \
$(LRDF_LIBS) \
$(GST_LIBS)
libgstladspa_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstladspa_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
noinst_HEADERS = gstladspa.h
noinst_HEADERS = \
gstladspautils.h \
gstladspafilter.h \
gstladspasource.h \
gstladspasink.h \
gstladspa.h
This diff is collapsed.
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) 2013 Juan Manuel Borges Caño <juanmabcmail@gmail.com>
*
* gstladspa.h: Header for LADSPA plugin
*
......@@ -19,58 +20,15 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_LADSPA_H__
#define __GST_LADSPA_H__
#include <ladspa.h>
#include <gst/gst.h>
#include <gst/signalprocessor/gstsignalprocessor.h>
G_BEGIN_DECLS
typedef struct _ladspa_control_info {
gchar *name;
gchar *param_name;
gfloat lowerbound, upperbound;
gfloat def;
gboolean lower, upper, samplerate;
gboolean toggled, logarithmic, integer, writable;
} ladspa_control_info;
typedef struct _GstLADSPA GstLADSPA;
typedef struct _GstLADSPAClass GstLADSPAClass;
struct _GstLADSPA {
GstSignalProcessor parent;
LADSPA_Descriptor *descriptor;
LADSPA_Handle *handle;
gboolean activated;
gboolean inplace_broken;
};
struct _GstLADSPAClass {
GstSignalProcessorClass parent_class;
LADSPA_Descriptor *descriptor;
gint *audio_in_portnums;
gint *audio_out_portnums;
gint *control_in_portnums;
gint *control_out_portnums;
};
extern GQuark descriptor_quark;
G_END_DECLS
#endif /* __GST_LADSPA_H__ */
/* GStreamer LADSPA filter category
* Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
* 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
* 2003 Andy Wingo <wingo at pobox.com>
* Copyright (C) 2013 Juan Manuel Borges Caño <juanmabcmail@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstladspafilter.h"
#include "gstladspa.h"
#include "gstladspautils.h"
GST_DEBUG_CATEGORY_EXTERN (ladspa_debug);
#define GST_CAT_DEFAULT ladspa_debug
#define GST_LADSPA_FILTER_CLASS_TAGS "Filter/Effect/Audio/LADSPA"
static GstLADSPAFilterClass *gst_ladspa_filter_type_parent_class = NULL;
/*
* Assumes only same format (base of AudioFilter), not same channels.
*/
void
gst_my_audio_filter_class_add_pad_templates (GstAudioFilterClass * audio_class,
GstCaps * srccaps, GstCaps * sinkcaps)
{
GstElementClass *elem_class = GST_ELEMENT_CLASS (audio_class);
GstPadTemplate *pad_template;
g_return_if_fail (GST_IS_CAPS (srccaps) && GST_IS_CAPS (sinkcaps));
pad_template =
gst_pad_template_new (GST_BASE_TRANSFORM_SRC_NAME, GST_PAD_SRC,
GST_PAD_ALWAYS, srccaps);
gst_element_class_add_pad_template (elem_class, pad_template);
pad_template =
gst_pad_template_new (GST_BASE_TRANSFORM_SINK_NAME, GST_PAD_SINK,
GST_PAD_ALWAYS, sinkcaps);
gst_element_class_add_pad_template (elem_class, pad_template);
}
static GstCaps *
gst_ladspa_filter_type_fixate_caps (GstBaseTransform * base,
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
GstStructure *structure;
gint rate;
structure = gst_caps_get_structure (caps, 0);
if (G_UNLIKELY (!gst_structure_get_int (structure, "rate", &rate)))
return othercaps;
othercaps = gst_caps_truncate (othercaps);
othercaps = gst_caps_make_writable (othercaps);
structure = gst_caps_get_structure (othercaps, 0);
gst_structure_fixate_field_nearest_int (structure, "rate", rate);
return othercaps;
}
static GstCaps *
gst_ladspa_filter_type_transform_caps (GstBaseTransform * base,
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
GstCaps *srccaps, *sinkcaps;
GstCaps *ret = NULL;
srccaps = gst_pad_get_pad_template_caps (GST_BASE_TRANSFORM_SRC_PAD (base));
sinkcaps = gst_pad_get_pad_template_caps (GST_BASE_TRANSFORM_SINK_PAD (base));
switch (direction) {
case GST_PAD_SINK:
if (gst_caps_can_intersect (caps, sinkcaps))
ret = gst_caps_copy (srccaps);
else
ret = gst_caps_new_empty ();
break;
case GST_PAD_SRC:
if (gst_caps_can_intersect (caps, srccaps))
ret = gst_caps_copy (sinkcaps);
else
ret = gst_caps_new_empty ();
break;
default:
g_assert_not_reached ();
}
GST_DEBUG_OBJECT (ladspa_debug, "transformed %" GST_PTR_FORMAT, ret);
if (filter) {
GstCaps *intersection;
GST_DEBUG_OBJECT (ladspa_debug, "Using filter caps %" GST_PTR_FORMAT,
filter);
intersection =
gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (ret);
ret = intersection;
GST_DEBUG_OBJECT (ladspa_debug, "Intersection %" GST_PTR_FORMAT, ret);
}
return ret;
}
static GstFlowReturn
gst_ladspa_filter_type_prepare_output_buffer (GstBaseTransform * base,
GstBuffer * inbuf, GstBuffer ** outbuf)
{
GstLADSPAFilter *ladspa = GST_LADSPA_FILTER (base);
GstLADSPAFilterClass *ladspa_class = GST_LADSPA_FILTER_GET_CLASS (ladspa);
guint samples;
samples =
gst_buffer_get_size (inbuf) / sizeof (LADSPA_Data) /
ladspa_class->ladspa.count.audio.in;
if (!gst_base_transform_is_in_place (base)) {
*outbuf =
gst_buffer_new_allocate (NULL,
samples * sizeof (LADSPA_Data) * ladspa_class->ladspa.count.audio.out,
NULL);
*outbuf = gst_buffer_make_writable (*outbuf);
return GST_FLOW_OK;
} else {
return
GST_BASE_TRANSFORM_CLASS
(gst_ladspa_filter_type_parent_class)->prepare_output_buffer (base,
inbuf, outbuf);
}
}
static gboolean
gst_ladspa_filter_type_setup (GstAudioFilter * audio,
const GstAudioInfo * info)
{
GstLADSPAFilter *ladspa = GST_LADSPA_FILTER (audio);
return gst_ladspa_setup (&ladspa->ladspa, GST_AUDIO_INFO_RATE (info));
}
static gboolean
gst_ladspa_filter_type_cleanup (GstBaseTransform * base)
{
GstLADSPAFilter *ladspa = GST_LADSPA_FILTER (base);
return gst_ladspa_cleanup (&ladspa->ladspa);
}
static GstFlowReturn
gst_ladspa_filter_type_transform_ip (GstBaseTransform * base,
GstBuffer * buf)
{
GstLADSPAFilter *ladspa = GST_LADSPA_FILTER (base);
GstMapInfo map;
guint samples;
gst_buffer_map (buf, &map, GST_MAP_READWRITE);
samples =
map.size / sizeof (LADSPA_Data) / ladspa->ladspa.klass->count.audio.in;
gst_ladspa_transform (&ladspa->ladspa, map.data, samples, map.data);
gst_buffer_unmap (buf, &map);
return GST_FLOW_OK;
}
static GstFlowReturn
gst_ladspa_filter_type_transform (GstBaseTransform * base,
GstBuffer * inbuf, GstBuffer * outbuf)
{
GstLADSPAFilter *ladspa = GST_LADSPA_FILTER (base);
GstMapInfo inmap, outmap;
guint samples;
gst_buffer_map (inbuf, &inmap, GST_MAP_READ);
gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE);
samples =
inmap.size / sizeof (LADSPA_Data) / ladspa->ladspa.klass->count.audio.in;
gst_ladspa_transform (&ladspa->ladspa, outmap.data, samples, inmap.data);
gst_buffer_unmap (outbuf, &outmap);
gst_buffer_unmap (inbuf, &inmap);
return GST_FLOW_OK;
}
static void
gst_ladspa_filter_type_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstLADSPAFilter *ladspa = GST_LADSPA_FILTER (object);
gst_ladspa_object_set_property (&ladspa->ladspa, object, prop_id, value,
pspec);
}
static void
gst_ladspa_filter_type_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstLADSPAFilter *ladspa = GST_LADSPA_FILTER (object);
gst_ladspa_object_get_property (&ladspa->ladspa, object, prop_id, value,
pspec);
}
static void
gst_ladspa_filter_type_init (GstLADSPAFilter * ladspa,
LADSPA_Descriptor * desc)
{
GstBaseTransform *base = GST_BASE_TRANSFORM (ladspa);
GstLADSPAFilterClass *ladspa_class = GST_LADSPA_FILTER_GET_CLASS (ladspa);
gst_ladspa_init (&ladspa->ladspa, &ladspa_class->ladspa);
/* even if channels are different LADSPA still maintains same samples */
gst_base_transform_set_in_place (base,
ladspa_class->ladspa.count.audio.in ==
ladspa_class->ladspa.count.audio.out
&& !LADSPA_IS_INPLACE_BROKEN (ladspa_class->ladspa.descriptor->
Properties));
}
static void
gst_ladspa_filter_type_dispose (GObject * object)
{
GstBaseTransform *base = GST_BASE_TRANSFORM (object);
gst_ladspa_filter_type_cleanup (base);
G_OBJECT_CLASS (gst_ladspa_filter_type_parent_class)->dispose (object);
}
static void
gst_ladspa_filter_type_finalize (GObject * object)
{
GstLADSPAFilter *ladspa = GST_LADSPA_FILTER (object);
gst_ladspa_finalize (&ladspa->ladspa);
G_OBJECT_CLASS (gst_ladspa_filter_type_parent_class)->finalize (object);
}
/*
* It is okay for plugins to 'leak' a one-time allocation. This will be freed when
* the application exits. When the plugins are scanned for the first time, this is
* done from a separate process to not impose the memory overhead on the calling
* application (among other reasons). Hence no need for class_finalize.
*/
static void
gst_ladspa_filter_type_base_init (GstLADSPAFilterClass * ladspa_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ladspa_class);
GstElementClass *elem_class = GST_ELEMENT_CLASS (ladspa_class);
GstAudioFilterClass *audio_class = GST_AUDIO_FILTER_CLASS (ladspa_class);
LADSPA_Descriptor *desc;
desc =
g_type_get_qdata (G_OBJECT_CLASS_TYPE (object_class), descriptor_quark);
g_assert (desc);
gst_ladspa_class_init (&ladspa_class->ladspa, desc);
gst_ladspa_element_class_set_metadata (&ladspa_class->ladspa, elem_class,
GST_LADSPA_FILTER_CLASS_TAGS);
gst_ladspa_filter_type_class_add_pad_templates (&ladspa_class->ladspa,
audio_class);
}
static void
gst_ladspa_filter_type_base_finalize (GstLADSPAFilterClass * ladspa_class)
{
gst_ladspa_class_finalize (&ladspa_class->ladspa);
}
static void
gst_ladspa_filter_type_class_init (GstLADSPAFilterClass * ladspa_class,
LADSPA_Descriptor * desc)
{
GObjectClass *object_class = G_OBJECT_CLASS (ladspa_class);
GstBaseTransformClass *base_class = GST_BASE_TRANSFORM_CLASS (ladspa_class);
GstAudioFilterClass *audio_class = GST_AUDIO_FILTER_CLASS (ladspa_class);
GST_DEBUG ("LADSPA filter class %p", ladspa_class);
gst_ladspa_filter_type_parent_class =
g_type_class_peek_parent (ladspa_class);
object_class->dispose =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_dispose);
object_class->finalize =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_finalize);
object_class->set_property =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_set_property);
object_class->get_property =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_get_property);
base_class->fixate_caps =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_fixate_caps);
base_class->transform_caps =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_transform_caps);
base_class->prepare_output_buffer =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_prepare_output_buffer);
base_class->transform =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_transform);
base_class->transform_ip =
GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_transform_ip);
audio_class->setup = GST_DEBUG_FUNCPTR (gst_ladspa_filter_type_setup);
gst_ladspa_object_class_install_properties (&ladspa_class->ladspa,
object_class, 1);
}
G_DEFINE_ABSTRACT_TYPE (GstLADSPAFilter, gst_ladspa_filter,
GST_TYPE_AUDIO_FILTER);
static void
gst_ladspa_filter_init (GstLADSPAFilter * ladspa)
{
}
static void
gst_ladspa_filter_class_init (GstLADSPAFilterClass * ladspa_class)
{
}
/*
* Construct the type.
*/
void
ladspa_describe_filter_plugin (GstPlugin * plugin,
const gchar * filename, const LADSPA_Descriptor * desc)
{
GTypeInfo info = {
sizeof (GstLADSPAFilterClass),
(GBaseInitFunc) gst_ladspa_filter_type_base_init,
(GBaseFinalizeFunc) gst_ladspa_filter_type_base_finalize,
(GClassInitFunc) gst_ladspa_filter_type_class_init,
NULL,
desc,
sizeof (GstLADSPAFilter),
0,
(GInstanceInitFunc) gst_ladspa_filter_type_init,
NULL
};
gchar *tmp;
tmp = g_strdup_printf ("ladspa-%s-%s", filename, desc->Label);
ladspa_register_plugin (plugin, GST_TYPE_LADSPA_FILTER, tmp, &info,
descriptor_quark, filename, desc);
g_free (tmp);
}
/* GStreamer
* Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) 2013 Juan Manuel Borges Caño <juanmabcmail@gmail.com>
*
* gstladspafilter.h: Header for LADSPA filter
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_LADSPA_FILTER_H__
#define __GST_LADSPA_FILTER_H__
#include <gst/gst.h>
#include <gst/audio/gstaudiofilter.h>
#include "gstladspautils.h"
G_BEGIN_DECLS
#define GST_TYPE_LADSPA_FILTER (gst_ladspa_filter_get_type())
#define GST_LADSPA_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LADSPA_FILTER,GstLADSPAFilter))
#define GST_LADSPA_FILTER_CAST(obj) ((GstLADSPAFilter *) (obj))
#define GST_LADSPA_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LADSPA_FILTER,GstLADSPAFilterClass))
#define GST_LADSPA_FILTER_CLASS_CAST(klass) ((GstLADSPAFilterClass *) (klass))
#define GST_LADSPA_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_LADSPA_FILTER,GstLADSPAFilterClass))
#define GST_IS_LADSPA_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LADSPA_FILTER))
#define GST_IS_LADSPA_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LADSPA_FILTER))
typedef struct _GstLADSPAFilter GstLADSPAFilter;
typedef struct _GstLADSPAFilterClass GstLADSPAFilterClass;
struct _GstLADSPAFilter
{
GstAudioFilter parent;
GstLADSPA ladspa;
};
struct _GstLADSPAFilterClass
{
GstAudioFilterClass parent_class;
GstLADSPAClass ladspa;
};
GType
gst_ladspa_filter_get_type (void);
void
ladspa_describe_filter_plugin (GstPlugin * plugin,
const gchar * filename, const LADSPA_Descriptor * desc);
void
gst_my_audio_filter_class_add_pad_templates (GstAudioFilterClass * audio_class,
GstCaps * srccaps, GstCaps * sinkcaps);
G_END_DECLS
#endif /* __GST_LADSPA_FILTER_H__ */
/* GStreamer LADSPA sink category
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
* 2003 Andy Wingo <wingo at pobox.com>
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com> (fakesink)
* Copyright (C) 2013 Juan Manuel Borges Caño <juanmabcmail@gmail.com>
*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstladspasink.h"
#include "gstladspa.h"
#include "gstladspautils.h"
#include <gst/base/gstbasetransform.h>
#include <string.h>
GST_DEBUG_CATEGORY_EXTERN (ladspa_debug);
#define GST_CAT_DEFAULT ladspa_debug
#define GST_LADSPA_SINK_CLASS_TAGS "Sink/Audio/LADSPA"
#define GST_LADSPA_SINK_DEFAULT_SYNC TRUE
#define GST_LADSPA_SINK_DEFAULT_CAN_ACTIVATE_PUSH TRUE
#define GST_LADSPA_SINK_DEFAULT_CAN_ACTIVATE_PULL FALSE
#define GST_LADSPA_SINK_DEFAULT_NUM_BUFFERS -1
enum
{
GST_LADSPA_SINK_PROP_0,
GST_LADSPA_SINK_PROP_CAN_ACTIVATE_PUSH,
GST_LADSPA_SINK_PROP_CAN_ACTIVATE_PULL,
GST_LADSPA_SINK_PROP_NUM_BUFFERS,
GST_LADSPA_SINK_PROP_LAST
};
static GstLADSPASinkClass *gst_ladspa_sink_type_parent_class = NULL;
/*
* Boilerplates BaseSink add pad.
*/
void