mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
freeverb: port to 1.0
This commit is contained in:
parent
09764eca37
commit
998cfde158
4 changed files with 110 additions and 135 deletions
|
@ -317,7 +317,6 @@ dnl Make sure you have a space before and after all plugins
|
||||||
GST_PLUGINS_NONPORTED=" aiff \
|
GST_PLUGINS_NONPORTED=" aiff \
|
||||||
cdxaparse \
|
cdxaparse \
|
||||||
dccp faceoverlay \
|
dccp faceoverlay \
|
||||||
freeverb \
|
|
||||||
hdvparse ivfparse jp2kdecimator \
|
hdvparse ivfparse jp2kdecimator \
|
||||||
kate librfb \
|
kate librfb \
|
||||||
mve mythtv nsf nuvdemux \
|
mve mythtv nsf nuvdemux \
|
||||||
|
|
|
@ -5,8 +5,14 @@ libgstfreeverb_la_SOURCES = gstfreeverb.c
|
||||||
|
|
||||||
# flags used to compile this plugin
|
# flags used to compile this plugin
|
||||||
# add other _CFLAGS and _LIBS as needed
|
# add other _CFLAGS and _LIBS as needed
|
||||||
libgstfreeverb_la_CFLAGS = $(GST_CFLAGS) $(GST_CONTROLLER_CFLAGS)
|
libgstfreeverb_la_CFLAGS = $(GST_CFLAGS) \
|
||||||
libgstfreeverb_la_LIBADD = $(GST_BASE_LIBS) $(GST_CONTROLLER_LIBS) $(GST_LIBS)
|
$(GST_BASE_CFLAGS) \
|
||||||
|
$(GST_PLUGINS_BASE_CFLAGS)
|
||||||
|
libgstfreeverb_la_LIBADD = $(GST_LIBS) \
|
||||||
|
$(GST_BASE_LIBS) \
|
||||||
|
$(GST_PLUGINS_BASE_LIBS) \
|
||||||
|
-lgstaudio-$(GST_API_VERSION) \
|
||||||
|
$(LIBM)
|
||||||
libgstfreeverb_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstfreeverb_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
libgstfreeverb_la_LIBTOOLFLAGS = --tag=disable-static
|
libgstfreeverb_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
|
||||||
|
|
|
@ -52,10 +52,10 @@
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstbasetransform.h>
|
#include <gst/base/gstbasetransform.h>
|
||||||
#include <gst/controller/gstcontroller.h>
|
|
||||||
|
|
||||||
#include "gstfreeverb.h"
|
#include "gstfreeverb.h"
|
||||||
|
|
||||||
|
@ -74,41 +74,27 @@ enum
|
||||||
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("audio/x-raw-float, "
|
GST_STATIC_CAPS ("audio/x-raw, "
|
||||||
"rate = (int) [ 1, MAX ], "
|
"format = (string) { " GST_AUDIO_NE (F32) ", " GST_AUDIO_NE (S16) "}, "
|
||||||
"channels = (int) [ 1, 2 ], "
|
"rate = (int) [ 1, MAX ], " "channels = (int) 1, "
|
||||||
"endianness = (int) BYTE_ORDER, " "width = (int) 32; "
|
"layout = (string) interleaved;"
|
||||||
"audio/x-raw-int, "
|
"audio/x-raw, "
|
||||||
"rate = (int) [ 1, MAX ], "
|
"format = (string) { " GST_AUDIO_NE (F32) ", " GST_AUDIO_NE (S16) "}, "
|
||||||
"channels = (int) [ 1, 2 ], "
|
"rate = (int) [ 1, MAX ], " "channels = (int) 2, "
|
||||||
"endianness = (int) BYTE_ORDER, "
|
"layout = (string) interleaved, " "channel-mask = (bitmask) 0x3")
|
||||||
"width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("audio/x-raw-float, "
|
GST_STATIC_CAPS ("audio/x-raw, "
|
||||||
"rate = (int) [ 1, MAX ], "
|
"format = (string) { " GST_AUDIO_NE (F32) ", " GST_AUDIO_NE (S16) "}, "
|
||||||
"channels = (int) 2, "
|
"rate = (int) [ 1, MAX ], " "channels = (int) 2, "
|
||||||
"endianness = (int) BYTE_ORDER, " "width = (int) 32; "
|
"layout = (string) interleaved, " "channel-mask = (bitmask) 0x3")
|
||||||
"audio/x-raw-int, "
|
|
||||||
"rate = (int) [ 1, MAX ], "
|
|
||||||
"channels = (int) 2, "
|
|
||||||
"endianness = (int) BYTE_ORDER, "
|
|
||||||
"width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#define _do_init(type) { \
|
G_DEFINE_TYPE_WITH_CODE (GstFreeverb, gst_freeverb, GST_TYPE_BASE_TRANSFORM,
|
||||||
const GInterfaceInfo preset_interface_info = { NULL, NULL, NULL }; \
|
G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
|
||||||
g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_interface_info); \
|
|
||||||
\
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_freeverb_debug, "freeverb", 0, \
|
|
||||||
"freeverb element"); \
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_BOILERPLATE_FULL (GstFreeverb, gst_freeverb, GstBaseTransform,
|
|
||||||
GST_TYPE_BASE_TRANSFORM, _do_init);
|
|
||||||
|
|
||||||
static void gst_freeverb_set_property (GObject * object, guint prop_id,
|
static void gst_freeverb_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec);
|
const GValue * value, GParamSpec * pspec);
|
||||||
|
@ -118,9 +104,9 @@ static void gst_freeverb_get_property (GObject * object, guint prop_id,
|
||||||
static void gst_freeverb_finalize (GObject * object);
|
static void gst_freeverb_finalize (GObject * object);
|
||||||
|
|
||||||
static gboolean gst_freeverb_get_unit_size (GstBaseTransform * base,
|
static gboolean gst_freeverb_get_unit_size (GstBaseTransform * base,
|
||||||
GstCaps * caps, guint * size);
|
GstCaps * caps, gsize * size);
|
||||||
static GstCaps *gst_freeverb_transform_caps (GstBaseTransform * base,
|
static GstCaps *gst_freeverb_transform_caps (GstBaseTransform * base,
|
||||||
GstPadDirection direction, GstCaps * caps);
|
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
|
||||||
static gboolean gst_freeverb_set_caps (GstBaseTransform * base,
|
static gboolean gst_freeverb_set_caps (GstBaseTransform * base,
|
||||||
GstCaps * incaps, GstCaps * outcaps);
|
GstCaps * incaps, GstCaps * outcaps);
|
||||||
|
|
||||||
|
@ -399,28 +385,20 @@ freeverb_revmodel_free (GstFreeverb * filter)
|
||||||
|
|
||||||
/* GObject vmethod implementations */
|
/* GObject vmethod implementations */
|
||||||
|
|
||||||
static void
|
|
||||||
gst_freeverb_base_init (gpointer klass)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_static_pad_template_get (&src_template));
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_static_pad_template_get (&sink_template));
|
|
||||||
gst_element_class_set_static_metadata (element_class, "Stereo positioning",
|
|
||||||
"Filter/Effect/Audio",
|
|
||||||
"Reverberation/room effect", "Stefan Sauer <ensonic@users.sf.net>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_freeverb_class_init (GstFreeverbClass * klass)
|
gst_freeverb_class_init (GstFreeverbClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class;
|
GObjectClass *gobject_class;
|
||||||
|
GstElementClass *element_class;
|
||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (GstFreeverbPrivate));
|
g_type_class_add_private (klass, sizeof (GstFreeverbPrivate));
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (gst_freeverb_debug, "freeverb", 0,
|
||||||
|
"freeverb element");
|
||||||
|
|
||||||
gobject_class = (GObjectClass *) klass;
|
gobject_class = (GObjectClass *) klass;
|
||||||
|
element_class = (GstElementClass *) klass;
|
||||||
|
|
||||||
gobject_class->set_property = gst_freeverb_set_property;
|
gobject_class->set_property = gst_freeverb_set_property;
|
||||||
gobject_class->get_property = gst_freeverb_get_property;
|
gobject_class->get_property = gst_freeverb_get_property;
|
||||||
gobject_class->finalize = gst_freeverb_finalize;
|
gobject_class->finalize = gst_freeverb_finalize;
|
||||||
|
@ -445,6 +423,16 @@ gst_freeverb_class_init (GstFreeverbClass * klass)
|
||||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
|
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
gst_element_class_set_static_metadata (element_class,
|
||||||
|
"Reverberation/room effect", "Filter/Effect/Audio",
|
||||||
|
"Add reverberation to audio streams",
|
||||||
|
"Stefan Sauer <ensonic@users.sf.net>");
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_static_pad_template_get (&src_template));
|
||||||
|
gst_element_class_add_pad_template (element_class,
|
||||||
|
gst_static_pad_template_get (&sink_template));
|
||||||
|
|
||||||
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size =
|
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size =
|
||||||
GST_DEBUG_FUNCPTR (gst_freeverb_get_unit_size);
|
GST_DEBUG_FUNCPTR (gst_freeverb_get_unit_size);
|
||||||
GST_BASE_TRANSFORM_CLASS (klass)->transform_caps =
|
GST_BASE_TRANSFORM_CLASS (klass)->transform_caps =
|
||||||
|
@ -456,15 +444,13 @@ gst_freeverb_class_init (GstFreeverbClass * klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_freeverb_init (GstFreeverb * filter, GstFreeverbClass * klass)
|
gst_freeverb_init (GstFreeverb * filter)
|
||||||
{
|
{
|
||||||
filter->priv =
|
filter->priv =
|
||||||
G_TYPE_INSTANCE_GET_PRIVATE (filter, GST_TYPE_FREEVERB,
|
G_TYPE_INSTANCE_GET_PRIVATE (filter, GST_TYPE_FREEVERB,
|
||||||
GstFreeverbPrivate);
|
GstFreeverbPrivate);
|
||||||
|
|
||||||
filter->width = 0;
|
gst_audio_info_init (&filter->info);
|
||||||
filter->channels = 0;
|
|
||||||
filter->format_float = FALSE;
|
|
||||||
filter->process = NULL;
|
filter->process = NULL;
|
||||||
|
|
||||||
gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
|
gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
|
||||||
|
@ -479,33 +465,32 @@ gst_freeverb_finalize (GObject * object)
|
||||||
|
|
||||||
freeverb_revmodel_free (filter);
|
freeverb_revmodel_free (filter);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (gst_freeverb_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_freeverb_set_process_function (GstFreeverb * filter)
|
gst_freeverb_set_process_function (GstFreeverb * filter, GstAudioInfo * info)
|
||||||
{
|
{
|
||||||
gint channel_index, format_index;
|
gint channel_index, format_index;
|
||||||
|
const GstAudioFormatInfo *finfo = info->finfo;
|
||||||
|
|
||||||
/* set processing function */
|
/* set processing function */
|
||||||
channel_index = filter->channels - 1;
|
channel_index = GST_AUDIO_INFO_CHANNELS (info) - 1;
|
||||||
if (channel_index > 1 || channel_index < 0) {
|
if (channel_index > 1 || channel_index < 0) {
|
||||||
filter->process = NULL;
|
filter->process = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
format_index = (filter->format_float) ? 1 : 0;
|
format_index = GST_AUDIO_FORMAT_INFO_IS_FLOAT (finfo) ? 1 : 0;
|
||||||
|
|
||||||
filter->process = process_functions[channel_index][format_index];
|
filter->process = process_functions[channel_index][format_index];
|
||||||
|
|
||||||
g_assert (filter->process);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_freeverb_init_rev_model (GstFreeverb * filter)
|
gst_freeverb_init_rev_model (GstFreeverb * filter)
|
||||||
{
|
{
|
||||||
gfloat srfactor = filter->rate / 44100.0f;
|
gfloat srfactor = GST_AUDIO_INFO_RATE (&filter->info) / 44100.0f;
|
||||||
GstFreeverbPrivate *priv = filter->priv;
|
GstFreeverbPrivate *priv = filter->priv;
|
||||||
|
|
||||||
freeverb_revmodel_free (filter);
|
freeverb_revmodel_free (filter);
|
||||||
|
@ -624,44 +609,55 @@ gst_freeverb_get_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_freeverb_get_unit_size (GstBaseTransform * base, GstCaps * caps,
|
gst_freeverb_get_unit_size (GstBaseTransform * base, GstCaps * caps,
|
||||||
guint * size)
|
gsize * size)
|
||||||
{
|
{
|
||||||
gint width, channels;
|
GstAudioInfo info;
|
||||||
GstStructure *structure;
|
|
||||||
gboolean ret;
|
|
||||||
|
|
||||||
g_assert (size);
|
g_assert (size);
|
||||||
|
|
||||||
/* this works for both float and int */
|
if (!gst_audio_info_from_caps (&info, caps))
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
return FALSE;
|
||||||
ret = gst_structure_get_int (structure, "width", &width);
|
|
||||||
ret &= gst_structure_get_int (structure, "channels", &channels);
|
|
||||||
|
|
||||||
*size = width * channels / 8;
|
*size = GST_AUDIO_INFO_BPF (&info);
|
||||||
|
|
||||||
GST_INFO_OBJECT (base, "unit size: %u", *size);
|
GST_INFO_OBJECT (base, "unit size: %u", *size);
|
||||||
|
|
||||||
return ret;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_freeverb_transform_caps (GstBaseTransform * base,
|
gst_freeverb_transform_caps (GstBaseTransform * base,
|
||||||
GstPadDirection direction, GstCaps * caps)
|
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
|
||||||
{
|
{
|
||||||
GstCaps *res;
|
GstCaps *res;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
|
gint i;
|
||||||
|
|
||||||
/* transform caps gives one single caps so we can just replace
|
/* replace the channel property with our range. */
|
||||||
* the channel property with our range. */
|
|
||||||
res = gst_caps_copy (caps);
|
res = gst_caps_copy (caps);
|
||||||
structure = gst_caps_get_structure (res, 0);
|
for (i = 0; i < gst_caps_get_size (res); i++) {
|
||||||
|
structure = gst_caps_get_structure (res, i);
|
||||||
if (direction == GST_PAD_SRC) {
|
if (direction == GST_PAD_SRC) {
|
||||||
GST_INFO_OBJECT (base, "allow 1-2 channels");
|
GST_INFO_OBJECT (base, "[%d] allow 1-2 channels", i);
|
||||||
gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
|
gst_structure_set (structure, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
|
||||||
|
gst_structure_remove_field (structure, "channel-mask");
|
||||||
} else {
|
} else {
|
||||||
GST_INFO_OBJECT (base, "allow 2 channels");
|
GST_INFO_OBJECT (base, "[%d] allow 2 channels", i);
|
||||||
gst_structure_set (structure, "channels", G_TYPE_INT, 2, NULL);
|
gst_structure_set (structure, "channels", G_TYPE_INT, 2, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
GST_DEBUG_OBJECT (base, "transformed %" GST_PTR_FORMAT, res);
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
GstCaps *intersection;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (base, "Using filter caps %" GST_PTR_FORMAT, filter);
|
||||||
|
intersection =
|
||||||
|
gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
|
||||||
|
gst_caps_unref (res);
|
||||||
|
res = intersection;
|
||||||
|
GST_DEBUG_OBJECT (base, "Intersection %" GST_PTR_FORMAT, res);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -671,57 +667,28 @@ gst_freeverb_set_caps (GstBaseTransform * base, GstCaps * incaps,
|
||||||
GstCaps * outcaps)
|
GstCaps * outcaps)
|
||||||
{
|
{
|
||||||
GstFreeverb *filter = GST_FREEVERB (base);
|
GstFreeverb *filter = GST_FREEVERB (base);
|
||||||
const GstStructure *structure;
|
GstAudioInfo info;
|
||||||
gboolean ret;
|
|
||||||
gint width, rate;
|
|
||||||
const gchar *fmt;
|
|
||||||
|
|
||||||
/*GST_INFO ("incaps are %" GST_PTR_FORMAT, incaps); */
|
/*GST_INFO ("incaps are %" GST_PTR_FORMAT, incaps); */
|
||||||
|
if (!gst_audio_info_from_caps (&info, incaps))
|
||||||
|
goto no_format;
|
||||||
|
|
||||||
structure = gst_caps_get_structure (incaps, 0);
|
if (!gst_freeverb_set_process_function (filter, &info))
|
||||||
ret = gst_structure_get_int (structure, "channels", &filter->channels);
|
goto no_format;
|
||||||
if (!ret)
|
|
||||||
goto no_channels;
|
|
||||||
|
|
||||||
ret = gst_structure_get_int (structure, "width", &width);
|
filter->info = info;
|
||||||
if (!ret)
|
|
||||||
goto no_width;
|
|
||||||
filter->width = width / 8;
|
|
||||||
|
|
||||||
ret = gst_structure_get_int (structure, "rate", &rate);
|
|
||||||
if (!ret)
|
|
||||||
goto no_rate;
|
|
||||||
filter->rate = rate;
|
|
||||||
|
|
||||||
fmt = gst_structure_get_name (structure);
|
|
||||||
if (!strcmp (fmt, "audio/x-raw-int"))
|
|
||||||
filter->format_float = FALSE;
|
|
||||||
else
|
|
||||||
filter->format_float = TRUE;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (filter, "try to process %s input_1 with %d channels", fmt,
|
|
||||||
filter->channels);
|
|
||||||
|
|
||||||
ret = gst_freeverb_set_process_function (filter);
|
|
||||||
if (!ret)
|
|
||||||
GST_WARNING_OBJECT (filter, "can't process input_1 with %d channels",
|
|
||||||
filter->channels);
|
|
||||||
|
|
||||||
gst_freeverb_init_rev_model (filter);
|
gst_freeverb_init_rev_model (filter);
|
||||||
filter->drained = FALSE;
|
filter->drained = FALSE;
|
||||||
GST_INFO_OBJECT (base, "model configured");
|
GST_INFO_OBJECT (base, "model configured");
|
||||||
|
|
||||||
return ret;
|
return TRUE;
|
||||||
|
|
||||||
no_channels:
|
no_format:
|
||||||
GST_DEBUG_OBJECT (filter, "no channels in caps");
|
{
|
||||||
return ret;
|
GST_DEBUG ("invalid caps");
|
||||||
no_width:
|
return FALSE;
|
||||||
GST_DEBUG_OBJECT (filter, "no width in caps");
|
}
|
||||||
return ret;
|
|
||||||
no_rate:
|
|
||||||
GST_DEBUG_OBJECT (filter, "no rate in caps");
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -919,39 +886,47 @@ gst_freeverb_transform (GstBaseTransform * base, GstBuffer * inbuf,
|
||||||
GstBuffer * outbuf)
|
GstBuffer * outbuf)
|
||||||
{
|
{
|
||||||
GstFreeverb *filter = GST_FREEVERB (base);
|
GstFreeverb *filter = GST_FREEVERB (base);
|
||||||
guint num_samples = GST_BUFFER_SIZE (outbuf) / (2 * filter->width);
|
guint num_samples;
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
|
GstMapInfo inmap, outmap;
|
||||||
|
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (inbuf);
|
timestamp = GST_BUFFER_TIMESTAMP (inbuf);
|
||||||
timestamp =
|
timestamp =
|
||||||
gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);
|
gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);
|
||||||
|
|
||||||
|
gst_buffer_map (inbuf, &inmap, GST_MAP_READ);
|
||||||
|
gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE);
|
||||||
|
num_samples = outmap.size / (2 * GST_AUDIO_INFO_BPS (&filter->info));
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (filter, "processing %u samples at %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (filter, "processing %u samples at %" GST_TIME_FORMAT,
|
||||||
num_samples, GST_TIME_ARGS (timestamp));
|
num_samples, GST_TIME_ARGS (timestamp));
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (timestamp))
|
if (GST_CLOCK_TIME_IS_VALID (timestamp))
|
||||||
gst_object_sync_values (G_OBJECT (filter), timestamp);
|
gst_object_sync_values (GST_OBJECT (filter), timestamp);
|
||||||
|
|
||||||
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DISCONT))) {
|
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DISCONT))) {
|
||||||
filter->drained = FALSE;
|
filter->drained = FALSE;
|
||||||
}
|
}
|
||||||
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP))) {
|
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP))) {
|
||||||
if (filter->drained) {
|
if (filter->drained) {
|
||||||
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
|
memset (outmap.data, 0, outmap.size);
|
||||||
memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf));
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filter->drained = FALSE;
|
filter->drained = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
filter->drained = filter->process (filter, GST_BUFFER_DATA (inbuf),
|
if (!filter->drained) {
|
||||||
GST_BUFFER_DATA (outbuf), num_samples);
|
filter->drained =
|
||||||
|
filter->process (filter, inmap.data, outmap.data, num_samples);
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->drained) {
|
if (filter->drained) {
|
||||||
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
|
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_buffer_unmap (inbuf, &inmap);
|
||||||
|
gst_buffer_unmap (outbuf, &outmap);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,8 +934,6 @@ gst_freeverb_transform (GstBaseTransform * base, GstBuffer * inbuf,
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_init (GstPlugin * plugin)
|
plugin_init (GstPlugin * plugin)
|
||||||
{
|
{
|
||||||
gst_controller_init (NULL, NULL);
|
|
||||||
|
|
||||||
return gst_element_register (plugin, "freeverb",
|
return gst_element_register (plugin, "freeverb",
|
||||||
GST_RANK_NONE, GST_TYPE_FREEVERB);
|
GST_RANK_NONE, GST_TYPE_FREEVERB);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define __GST_FREEVERB_H__
|
#define __GST_FREEVERB_H__
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/audio/audio.h>
|
||||||
#include <gst/base/gstbasetransform.h>
|
#include <gst/base/gstbasetransform.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
@ -49,11 +50,7 @@ struct _GstFreeverb {
|
||||||
gfloat level;
|
gfloat level;
|
||||||
|
|
||||||
GstFreeverbProcessFunc process;
|
GstFreeverbProcessFunc process;
|
||||||
gint channels;
|
GstAudioInfo info;
|
||||||
gboolean format_float;
|
|
||||||
gint width;
|
|
||||||
gint method;
|
|
||||||
gint rate;
|
|
||||||
|
|
||||||
gboolean drained;
|
gboolean drained;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue