From 3c292543bc54008212153ac5b911df1275e47512 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 23 Feb 2012 12:03:24 +0100 Subject: [PATCH] audiofx: remove transform lock usage --- gst/audiofx/audioecho.c | 47 ++++++++++++++----------- gst/audiofx/audioecho.h | 2 ++ gst/audiofx/audiofxbasefirfilter.c | 71 ++++++++++++++++++++------------------ gst/audiofx/audiofxbasefirfilter.h | 2 ++ gst/audiofx/audiofxbaseiirfilter.c | 17 ++++++--- gst/audiofx/audiofxbaseiirfilter.h | 2 ++ 6 files changed, 83 insertions(+), 58 deletions(-) diff --git a/gst/audiofx/audioecho.c b/gst/audiofx/audioecho.c index 439bf74..da18dc2 100644 --- a/gst/audiofx/audioecho.c +++ b/gst/audiofx/audioecho.c @@ -160,6 +160,8 @@ gst_audio_echo_init (GstAudioEcho * self) self->intensity = 0.0; self->feedback = 0.0; + g_mutex_init (&self->lock); + gst_base_transform_set_in_place (GST_BASE_TRANSFORM (self), TRUE); } @@ -171,6 +173,8 @@ gst_audio_echo_finalize (GObject * object) g_free (self->buffer); self->buffer = NULL; + g_mutex_clear (&self->lock); + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -184,7 +188,7 @@ gst_audio_echo_set_property (GObject * object, guint prop_id, 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; @@ -197,13 +201,13 @@ gst_audio_echo_set_property (GObject * object, guint prop_id, 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; @@ -214,21 +218,21 @@ gst_audio_echo_set_property (GObject * object, guint prop_id, 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; @@ -243,24 +247,24 @@ gst_audio_echo_get_property (GObject * object, guint prop_id, 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); @@ -361,6 +365,7 @@ gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf) 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); @@ -387,6 +392,7 @@ gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf) 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; } @@ -398,6 +404,7 @@ gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf) self->process (self, map.data, num_samples); gst_buffer_unmap (buf, &map); + g_mutex_unlock (&self->lock); return GST_FLOW_OK; } diff --git a/gst/audiofx/audioecho.h b/gst/audiofx/audioecho.h index 9722d7d..1be3cbc 100644 --- a/gst/audiofx/audioecho.h +++ b/gst/audiofx/audioecho.h @@ -55,6 +55,8 @@ struct _GstAudioEcho guint buffer_pos; guint buffer_size; guint buffer_size_frames; + + GMutex lock; }; struct _GstAudioEchoClass diff --git a/gst/audiofx/audiofxbasefirfilter.c b/gst/audiofx/audiofxbasefirfilter.c index 264c303..a213b04 100644 --- a/gst/audiofx/audiofxbasefirfilter.c +++ b/gst/audiofx/audiofxbasefirfilter.c @@ -72,10 +72,10 @@ static gboolean gst_audio_fx_base_fir_filter_transform_size (GstBaseTransform * 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] @@ -452,29 +452,19 @@ gst_audio_fx_base_fir_filter_select_process_function (GstAudioFXBaseFIRFilter * } 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 @@ -493,7 +483,8 @@ gst_audio_fx_base_fir_filter_set_property (GObject * object, guint prop_id, return; } - GST_BASE_TRANSFORM_LOCK (self); + + g_mutex_lock (&self->lock); low_latency = g_value_get_boolean (value); if (self->low_latency != low_latency) { @@ -502,13 +493,13 @@ gst_audio_fx_base_fir_filter_set_property (GObject * object, guint prop_id, 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: @@ -547,7 +538,7 @@ gst_audio_fx_base_fir_filter_class_init (GstAudioFXBaseFIRFilterClass * klass) 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; @@ -593,6 +584,7 @@ gst_audio_fx_base_fir_filter_class_init (GstAudioFXBaseFIRFilterClass * klass) 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); @@ -613,8 +605,7 @@ gst_audio_fx_base_fir_filter_init (GstAudioFXBaseFIRFilter * self) 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 @@ -745,6 +736,7 @@ gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base, { 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); @@ -759,6 +751,7 @@ gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base, 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); } @@ -818,6 +811,7 @@ gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base, return GST_FLOW_ERROR; } + g_mutex_lock (&self->lock); stream_time = gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp); @@ -874,18 +868,20 @@ gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base, 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); @@ -903,6 +899,7 @@ gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base, 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: %" @@ -914,6 +911,12 @@ gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base, 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 @@ -945,10 +948,10 @@ gst_audio_fx_base_fir_filter_stop (GstBaseTransform * base) } 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)) { @@ -993,7 +996,9 @@ gst_audio_fx_base_fir_filter_query (GstPad * pad, GstObject * parent, break; } default: - res = gst_pad_query_default (pad, parent, query); + res = + GST_BASE_TRANSFORM_CLASS (parent_class)->query (trans, direction, + query); break; } return res; @@ -1029,7 +1034,7 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self, 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 @@ -1069,5 +1074,5 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self, gst_message_new_latency (GST_OBJECT (self))); } - GST_BASE_TRANSFORM_UNLOCK (self); + g_mutex_unlock (&self->lock); } diff --git a/gst/audiofx/audiofxbasefirfilter.h b/gst/audiofx/audiofxbasefirfilter.h index c9eeb1b..263c97d 100644 --- a/gst/audiofx/audiofxbasefirfilter.h +++ b/gst/audiofx/audiofxbasefirfilter.h @@ -84,6 +84,8 @@ struct _GstAudioFXBaseFIRFilter { guint64 start_off; /* start offset after a discont */ guint64 nsamples_out; /* number of output samples since last discont */ guint64 nsamples_in; /* number of input samples since last discont */ + + GMutex lock; }; struct _GstAudioFXBaseFIRFilterClass { diff --git a/gst/audiofx/audiofxbaseiirfilter.c b/gst/audiofx/audiofxbaseiirfilter.c index 79e06f0..2255449 100644 --- a/gst/audiofx/audiofxbaseiirfilter.c +++ b/gst/audiofx/audiofxbaseiirfilter.c @@ -62,7 +62,7 @@ static void process_32 (GstAudioFXBaseIIRFilter * filter, /* 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); @@ -89,8 +89,9 @@ gst_audio_fx_base_iir_filter_dispose (GObject * 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 @@ -104,7 +105,7 @@ gst_audio_fx_base_iir_filter_class_init (GstAudioFXBaseIIRFilterClass * klass) 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), @@ -129,6 +130,8 @@ gst_audio_fx_base_iir_filter_init (GstAudioFXBaseIIRFilter * filter) filter->nb = 0; filter->channels = NULL; filter->nchannels = 0; + + g_mutex_init (&filter->lock); } /* Evaluate the transfer function that corresponds to the IIR @@ -182,7 +185,7 @@ gst_audio_fx_base_iir_filter_set_coefficients (GstAudioFXBaseIIRFilter * filter, 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); @@ -230,7 +233,7 @@ gst_audio_fx_base_iir_filter_set_coefficients (GstAudioFXBaseIIRFilter * filter, } } - GST_BASE_TRANSFORM_UNLOCK (filter); + g_mutex_unlock (&filter->lock); } /* GstAudioFilter vmethod implementations */ @@ -243,6 +246,7 @@ gst_audio_fx_base_iir_filter_setup (GstAudioFilter * base, gboolean ret = TRUE; gint channels; + g_mutex_lock (&filter->lock); switch (GST_AUDIO_INFO_FORMAT (info)) { case GST_AUDIO_FORMAT_F32: filter->process = (GstAudioFXBaseIIRFilterProcessFunc) @@ -282,6 +286,7 @@ gst_audio_fx_base_iir_filter_setup (GstAudioFilter * base, } filter->nchannels = channels; } + g_mutex_unlock (&filter->lock); return ret; } @@ -374,7 +379,9 @@ gst_audio_fx_base_iir_filter_transform_ip (GstBaseTransform * base, 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); diff --git a/gst/audiofx/audiofxbaseiirfilter.h b/gst/audiofx/audiofxbaseiirfilter.h index 0534343..8cf91c8 100644 --- a/gst/audiofx/audiofxbaseiirfilter.h +++ b/gst/audiofx/audiofxbaseiirfilter.h @@ -61,6 +61,8 @@ struct _GstAudioFXBaseIIRFilter guint nb; GstAudioFXBaseIIRFilterChannelCtx *channels; guint nchannels; + + GMutex lock; }; struct _GstAudioFXBaseIIRFilterClass -- 2.7.4