self->intensity = 0.0;
self->feedback = 0.0;
+ g_mutex_init (&self->lock);
+
gst_base_transform_set_in_place (GST_BASE_TRANSFORM (self), TRUE);
}
g_free (self->buffer);
self->buffer = NULL;
+ g_mutex_clear (&self->lock);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
case PROP_DELAY:{
guint64 max_delay, delay;
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
delay = g_value_get_uint64 (value);
max_delay = self->max_delay;
self->delay = delay;
self->max_delay = MAX (delay, max_delay);
}
- GST_BASE_TRANSFORM_UNLOCK (self);
- }
+ g_mutex_unlock (&self->lock);
break;
+ }
case PROP_MAX_DELAY:{
guint64 max_delay, delay;
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
max_delay = g_value_get_uint64 (value);
delay = self->delay;
self->delay = delay;
self->max_delay = max_delay;
}
- GST_BASE_TRANSFORM_UNLOCK (self);
- }
+ g_mutex_unlock (&self->lock);
break;
+ }
case PROP_INTENSITY:{
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
self->intensity = g_value_get_float (value);
- GST_BASE_TRANSFORM_UNLOCK (self);
- }
+ g_mutex_unlock (&self->lock);
break;
+ }
case PROP_FEEDBACK:{
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
self->feedback = g_value_get_float (value);
- GST_BASE_TRANSFORM_UNLOCK (self);
- }
+ g_mutex_unlock (&self->lock);
break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
switch (prop_id) {
case PROP_DELAY:
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
g_value_set_uint64 (value, self->delay);
- GST_BASE_TRANSFORM_UNLOCK (self);
+ g_mutex_unlock (&self->lock);
break;
case PROP_MAX_DELAY:
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
g_value_set_uint64 (value, self->max_delay);
- GST_BASE_TRANSFORM_UNLOCK (self);
+ g_mutex_unlock (&self->lock);
break;
case PROP_INTENSITY:
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
g_value_set_float (value, self->intensity);
- GST_BASE_TRANSFORM_UNLOCK (self);
+ g_mutex_unlock (&self->lock);
break;
case PROP_FEEDBACK:
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
g_value_set_float (value, self->feedback);
- GST_BASE_TRANSFORM_UNLOCK (self);
+ g_mutex_unlock (&self->lock);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
GstClockTime timestamp, stream_time;
GstMapInfo map;
+ g_mutex_lock (&self->lock);
timestamp = GST_BUFFER_TIMESTAMP (buf);
stream_time =
gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);
self->buffer_pos = 0;
if (self->buffer == NULL) {
+ g_mutex_unlock (&self->lock);
GST_ERROR_OBJECT (self, "Failed to allocate %u bytes", self->buffer_size);
return GST_FLOW_ERROR;
}
self->process (self, map.data, num_samples);
gst_buffer_unmap (buf, &map);
+ g_mutex_unlock (&self->lock);
return GST_FLOW_OK;
}
static gboolean gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base,
const GstAudioInfo * info);
-static gboolean gst_audio_fx_base_fir_filter_query (GstPad * pad,
- GstObject * parent, GstQuery * query);
+static gboolean gst_audio_fx_base_fir_filter_query (GstBaseTransform * trans,
+ GstPadDirection direction, GstQuery * quer);
-/*
+/*
* The code below calculates the linear convolution:
*
* y[t] = \sum_{u=0}^{M-1} x[t - u] * h[u]
}
static void
-gst_audio_fx_base_fir_filter_dispose (GObject * object)
+gst_audio_fx_base_fir_filter_finalize (GObject * object)
{
GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (object);
g_free (self->buffer);
- self->buffer = NULL;
- self->buffer_length = 0;
-
g_free (self->kernel);
- self->kernel = NULL;
-
gst_fft_f64_free (self->fft);
- self->fft = NULL;
gst_fft_f64_free (self->ifft);
- self->ifft = NULL;
-
g_free (self->frequency_response);
- self->frequency_response = NULL;
-
g_free (self->fft_buffer);
- self->fft_buffer = NULL;
+ g_mutex_clear (&self->lock);
- G_OBJECT_CLASS (parent_class)->dispose (object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
return;
}
- GST_BASE_TRANSFORM_LOCK (self);
+
+ g_mutex_lock (&self->lock);
low_latency = g_value_get_boolean (value);
if (self->low_latency != low_latency) {
gst_audio_fx_base_fir_filter_select_process_function (self,
GST_AUDIO_FILTER_FORMAT (self), GST_AUDIO_FILTER_CHANNELS (self));
}
- GST_BASE_TRANSFORM_UNLOCK (self);
+ g_mutex_unlock (&self->lock);
break;
}
case PROP_DRAIN_ON_CHANGES:{
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
self->drain_on_changes = g_value_get_boolean (value);
- GST_BASE_TRANSFORM_UNLOCK (self);
+ g_mutex_unlock (&self->lock);
break;
}
default:
GST_DEBUG_CATEGORY_INIT (gst_audio_fx_base_fir_filter_debug,
"audiofxbasefirfilter", 0, "FIR filter base class");
- gobject_class->dispose = gst_audio_fx_base_fir_filter_dispose;
+ gobject_class->finalize = gst_audio_fx_base_fir_filter_finalize;
gobject_class->set_property = gst_audio_fx_base_fir_filter_set_property;
gobject_class->get_property = gst_audio_fx_base_fir_filter_get_property;
trans_class->stop = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_stop);
trans_class->sink_event =
GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_sink_event);
+ trans_class->query = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_query);
trans_class->transform_size =
GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_transform_size);
filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_setup);
self->low_latency = DEFAULT_LOW_LATENCY;
self->drain_on_changes = DEFAULT_DRAIN_ON_CHANGES;
- gst_pad_set_query_function (GST_BASE_TRANSFORM (self)->srcpad,
- gst_audio_fx_base_fir_filter_query);
+ g_mutex_init (&self->lock);
}
void
{
GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
+ g_mutex_lock (&self->lock);
if (self->buffer) {
gst_audio_fx_base_fir_filter_push_residue (self);
g_free (self->buffer);
gst_audio_fx_base_fir_filter_select_process_function (self,
GST_AUDIO_INFO_FORMAT (info), GST_AUDIO_INFO_CHANNELS (info));
+ g_mutex_unlock (&self->lock);
return (self->process != NULL);
}
return GST_FLOW_ERROR;
}
+ g_mutex_lock (&self->lock);
stream_time =
gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);
g_assert (generated_samples <= output_samples);
self->nsamples_out += generated_samples;
if (generated_samples == 0)
- return GST_BASE_TRANSFORM_FLOW_DROPPED;
+ goto no_samples;
/* Calculate the number of samples we can push out now without outputting
* latency zeros in the beginning */
diff = ((gint64) self->nsamples_out) - ((gint64) self->latency);
- if (diff < 0) {
- return GST_BASE_TRANSFORM_FLOW_DROPPED;
- } else if (diff < generated_samples) {
+ if (diff < 0)
+ goto no_samples;
+
+ if (diff < generated_samples) {
gint64 tmp = diff;
diff = generated_samples - diff;
generated_samples = tmp;
}
+
gst_buffer_resize (outbuf, diff * bps * channels,
generated_samples * bps * channels);
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
}
+ g_mutex_unlock (&self->lock);
GST_DEBUG_OBJECT (self,
"Pushing buffer of size %" G_GSIZE_FORMAT " with timestamp: %"
GST_BUFFER_OFFSET_END (outbuf), generated_samples);
return GST_FLOW_OK;
+
+no_samples:
+ {
+ g_mutex_unlock (&self->lock);
+ return GST_BASE_TRANSFORM_FLOW_DROPPED;
+ }
}
static gboolean
}
static gboolean
-gst_audio_fx_base_fir_filter_query (GstPad * pad, GstObject * parent,
- GstQuery * query)
+gst_audio_fx_base_fir_filter_query (GstBaseTransform * trans,
+ GstPadDirection direction, GstQuery * query)
{
- GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (parent);
+ GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (trans);
gboolean res = TRUE;
switch (GST_QUERY_TYPE (query)) {
break;
}
default:
- res = gst_pad_query_default (pad, parent, query);
+ res =
+ GST_BASE_TRANSFORM_CLASS (parent_class)->query (trans, direction,
+ query);
break;
}
return res;
g_return_if_fail (kernel != NULL);
g_return_if_fail (self != NULL);
- GST_BASE_TRANSFORM_LOCK (self);
+ g_mutex_lock (&self->lock);
latency_changed = (self->latency != latency
|| (!self->low_latency && self->kernel_length < FFT_THRESHOLD
gst_message_new_latency (GST_OBJECT (self)));
}
- GST_BASE_TRANSFORM_UNLOCK (self);
+ g_mutex_unlock (&self->lock);
}
/* GObject vmethod implementations */
static void
-gst_audio_fx_base_iir_filter_dispose (GObject * object)
+gst_audio_fx_base_iir_filter_finalize (GObject * object)
{
GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (object);
g_free (filter->channels);
filter->channels = NULL;
}
+ g_mutex_clear (&filter->lock);
- G_OBJECT_CLASS (parent_class)->dispose (object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
GST_DEBUG_CATEGORY_INIT (gst_audio_fx_base_iir_filter_debug,
"audiofxbaseiirfilter", 0, "Audio IIR Filter Base Class");
- gobject_class->dispose = gst_audio_fx_base_iir_filter_dispose;
+ gobject_class->finalize = gst_audio_fx_base_iir_filter_finalize;
caps = gst_caps_from_string (ALLOWED_CAPS);
gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (klass),
filter->nb = 0;
filter->channels = NULL;
filter->nchannels = 0;
+
+ g_mutex_init (&filter->lock);
}
/* Evaluate the transfer function that corresponds to the IIR
g_return_if_fail (GST_IS_AUDIO_FX_BASE_IIR_FILTER (filter));
- GST_BASE_TRANSFORM_LOCK (filter);
+ g_mutex_lock (&filter->lock);
g_free (filter->a);
g_free (filter->b);
}
}
- GST_BASE_TRANSFORM_UNLOCK (filter);
+ g_mutex_unlock (&filter->lock);
}
/* GstAudioFilter vmethod implementations */
gboolean ret = TRUE;
gint channels;
+ g_mutex_lock (&filter->lock);
switch (GST_AUDIO_INFO_FORMAT (info)) {
case GST_AUDIO_FORMAT_F32:
filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
}
filter->nchannels = channels;
}
+ g_mutex_unlock (&filter->lock);
return ret;
}
gst_buffer_map (buf, &map, GST_MAP_READWRITE);
num_samples = map.size / GST_AUDIO_FILTER_BPS (filter);
+ g_mutex_lock (&filter->lock);
filter->process (filter, map.data, num_samples);
+ g_mutex_unlock (&filter->lock);
gst_buffer_unmap (buf, &map);