From 4b227159cba3b5953d85dd5358cefece06e5d35f Mon Sep 17 00:00:00 2001 From: Sebastian Dröge Date: Tue, 13 Jan 2009 08:24:25 +0000 Subject: gst/audiofx/: Use a custom mutex for protecting the instance fields instead of the GstObject lock. Using the latter c... Original commit message from CVS: * gst/audiofx/audiochebband.c: (gst_audio_cheb_band_class_init), (gst_audio_cheb_band_init), (gst_audio_cheb_band_finalize), (gst_audio_cheb_band_set_property): * gst/audiofx/audiochebband.h: * gst/audiofx/audiocheblimit.c: (gst_audio_cheb_limit_class_init), (gst_audio_cheb_limit_init), (gst_audio_cheb_limit_finalize), (gst_audio_cheb_limit_set_property): * gst/audiofx/audiocheblimit.h: * gst/audiofx/audiowsincband.c: (gst_audio_wsincband_class_init), (gst_audio_wsincband_init), (gst_audio_wsincband_finalize), (gst_audio_wsincband_set_property): * gst/audiofx/audiowsincband.h: * gst/audiofx/audiowsinclimit.c: (gst_audio_wsinclimit_class_init), (gst_audio_wsinclimit_init), (gst_audio_wsinclimit_finalize), (gst_audio_wsinclimit_set_property): * gst/audiofx/audiowsinclimit.h: Use a custom mutex for protecting the instance fields instead of the GstObject lock. Using the latter can lead to deadlocks, especially with the FIR filters when updating the latency. --- ChangeLog | 22 ++++++++++++++++++++++ gst/audiofx/audiochebband.c | 39 +++++++++++++++++++++++++++------------ gst/audiofx/audiochebband.h | 3 +++ gst/audiofx/audiocheblimit.c | 35 +++++++++++++++++++++++++---------- gst/audiofx/audiocheblimit.h | 3 +++ gst/audiofx/audiowsincband.c | 42 +++++++++++++++++++++++++----------------- gst/audiofx/audiowsincband.h | 4 +++- gst/audiofx/audiowsinclimit.c | 36 +++++++++++++++++++++++------------- gst/audiofx/audiowsinclimit.h | 4 +++- 9 files changed, 134 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12343bdf..afe32145 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2009-01-13 Sebastian Dröge + + * gst/audiofx/audiochebband.c: (gst_audio_cheb_band_class_init), + (gst_audio_cheb_band_init), (gst_audio_cheb_band_finalize), + (gst_audio_cheb_band_set_property): + * gst/audiofx/audiochebband.h: + * gst/audiofx/audiocheblimit.c: (gst_audio_cheb_limit_class_init), + (gst_audio_cheb_limit_init), (gst_audio_cheb_limit_finalize), + (gst_audio_cheb_limit_set_property): + * gst/audiofx/audiocheblimit.h: + * gst/audiofx/audiowsincband.c: (gst_audio_wsincband_class_init), + (gst_audio_wsincband_init), (gst_audio_wsincband_finalize), + (gst_audio_wsincband_set_property): + * gst/audiofx/audiowsincband.h: + * gst/audiofx/audiowsinclimit.c: (gst_audio_wsinclimit_class_init), + (gst_audio_wsinclimit_init), (gst_audio_wsinclimit_finalize), + (gst_audio_wsinclimit_set_property): + * gst/audiofx/audiowsinclimit.h: + Use a custom mutex for protecting the instance fields instead of + the GstObject lock. Using the latter can lead to deadlocks, especially + with the FIR filters when updating the latency. + 2009-01-11 Sebastian Dröge * gst/audiofx/Makefile.am: diff --git a/gst/audiofx/audiochebband.c b/gst/audiofx/audiochebband.c index 36aeb8de..bf9c205e 100644 --- a/gst/audiofx/audiochebband.c +++ b/gst/audiofx/audiochebband.c @@ -113,6 +113,7 @@ static void gst_audio_cheb_band_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_audio_cheb_band_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_audio_cheb_band_finalize (GObject * object); static gboolean gst_audio_cheb_band_setup (GstAudioFilter * filter, GstRingBufferSpec * format); @@ -164,6 +165,7 @@ gst_audio_cheb_band_class_init (GstAudioChebBandClass * klass) gobject_class->set_property = gst_audio_cheb_band_set_property; gobject_class->get_property = gst_audio_cheb_band_get_property; + gobject_class->finalize = gst_audio_cheb_band_finalize; g_object_class_install_property (gobject_class, PROP_MODE, g_param_spec_enum ("mode", "Mode", @@ -210,6 +212,8 @@ gst_audio_cheb_band_init (GstAudioChebBand * filter, filter->type = 1; filter->poles = 4; filter->ripple = 0.25; + + filter->lock = g_mutex_new (); } static void @@ -567,6 +571,17 @@ generate_coefficients (GstAudioChebBand * filter) } } +static void +gst_audio_cheb_band_finalize (GObject * object) +{ + GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (object); + + g_mutex_free (filter->lock); + filter->lock = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + static void gst_audio_cheb_band_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -575,40 +590,40 @@ gst_audio_cheb_band_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_MODE: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->mode = g_value_get_enum (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_TYPE: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->type = g_value_get_int (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_LOWER_FREQUENCY: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->lower_frequency = g_value_get_float (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_UPPER_FREQUENCY: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->upper_frequency = g_value_get_float (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_RIPPLE: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->ripple = g_value_get_float (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_POLES: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->poles = GST_ROUND_UP_4 (g_value_get_int (value)); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/gst/audiofx/audiochebband.h b/gst/audiofx/audiochebband.h index fae1a0c6..32610325 100644 --- a/gst/audiofx/audiochebband.h +++ b/gst/audiofx/audiochebband.h @@ -48,6 +48,9 @@ struct _GstAudioChebBand gfloat lower_frequency; gfloat upper_frequency; gfloat ripple; + + /* < private > */ + GMutex *lock; }; struct _GstAudioChebBandClass diff --git a/gst/audiofx/audiocheblimit.c b/gst/audiofx/audiocheblimit.c index 4d8d311d..b4efbb3a 100644 --- a/gst/audiofx/audiocheblimit.c +++ b/gst/audiofx/audiocheblimit.c @@ -109,6 +109,7 @@ static void gst_audio_cheb_limit_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_audio_cheb_limit_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_audio_cheb_limit_finalize (GObject * object); static gboolean gst_audio_cheb_limit_setup (GstAudioFilter * filter, GstRingBufferSpec * format); @@ -161,6 +162,7 @@ gst_audio_cheb_limit_class_init (GstAudioChebLimitClass * klass) gobject_class->set_property = gst_audio_cheb_limit_set_property; gobject_class->get_property = gst_audio_cheb_limit_get_property; + gobject_class->finalize = gst_audio_cheb_limit_finalize; g_object_class_install_property (gobject_class, PROP_MODE, g_param_spec_enum ("mode", "Mode", @@ -203,6 +205,8 @@ gst_audio_cheb_limit_init (GstAudioChebLimit * filter, filter->type = 1; filter->poles = 4; filter->ripple = 0.25; + + filter->lock = g_mutex_new (); } static void @@ -478,6 +482,17 @@ generate_coefficients (GstAudioChebLimit * filter) } } +static void +gst_audio_cheb_limit_finalize (GObject * object) +{ + GstAudioChebLimit *filter = GST_AUDIO_CHEB_LIMIT (object); + + g_mutex_free (filter->lock); + filter->lock = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + static void gst_audio_cheb_limit_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -486,34 +501,34 @@ gst_audio_cheb_limit_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_MODE: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->mode = g_value_get_enum (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_TYPE: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->type = g_value_get_int (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_CUTOFF: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->cutoff = g_value_get_float (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_RIPPLE: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->ripple = g_value_get_float (value); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; case PROP_POLES: - GST_OBJECT_LOCK (filter); + g_mutex_lock (filter->lock); filter->poles = GST_ROUND_UP_2 (g_value_get_int (value)); generate_coefficients (filter); - GST_OBJECT_UNLOCK (filter); + g_mutex_unlock (filter->lock); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/gst/audiofx/audiocheblimit.h b/gst/audiofx/audiocheblimit.h index 491f7494..6f798528 100644 --- a/gst/audiofx/audiocheblimit.h +++ b/gst/audiofx/audiocheblimit.h @@ -49,6 +49,9 @@ struct _GstAudioChebLimit gint poles; gfloat cutoff; gfloat ripple; + + /* < private > */ + GMutex *lock; }; struct _GstAudioChebLimitClass diff --git a/gst/audiofx/audiowsincband.c b/gst/audiofx/audiowsincband.c index 62034308..69bf5c19 100644 --- a/gst/audiofx/audiowsincband.c +++ b/gst/audiofx/audiowsincband.c @@ -26,13 +26,6 @@ * chapter 16 * available at http://www.dspguide.com/ * - * TODO: - Implement the convolution in place, probably only makes sense - * when using FFT convolution as currently the convolution itself - * is probably the bottleneck - * - Maybe allow cascading the filter to get a better stopband attenuation. - * Can be done by convolving a filter kernel with itself - * - Drop the first kernel_length/2 samples and append the same number of - * samples on EOS as the first few samples are essentialy zero. */ /** @@ -150,6 +143,7 @@ static void gst_audio_wsincband_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_audio_wsincband_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_audio_wsincband_finalize (GObject * object); static gboolean gst_audio_wsincband_setup (GstAudioFilter * base, GstRingBufferSpec * format); @@ -177,6 +171,7 @@ gst_audio_wsincband_class_init (GstAudioWSincBandClass * klass) gobject_class->set_property = gst_audio_wsincband_set_property; gobject_class->get_property = gst_audio_wsincband_get_property; + gobject_class->finalize = gst_audio_wsincband_finalize; /* FIXME: Don't use the complete possible range but restrict the upper boundary * so automatically generated UIs can use a slider */ @@ -218,6 +213,8 @@ gst_audio_wsincband_init (GstAudioWSincBand * self, self->upper_frequency = 0.0; self->mode = MODE_BAND_PASS; self->window = WINDOW_HAMMING; + + self->lock = g_mutex_new (); } static void @@ -352,6 +349,17 @@ gst_audio_wsincband_setup (GstAudioFilter * base, GstRingBufferSpec * format) return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format); } +static void +gst_audio_wsincband_finalize (GObject * object) +{ + GstAudioWSincBand *self = GST_AUDIO_WSINC_BAND (object); + + g_mutex_free (self->lock); + self->lock = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + static void gst_audio_wsincband_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -364,7 +372,7 @@ gst_audio_wsincband_set_property (GObject * object, guint prop_id, case PROP_LENGTH:{ gint val; - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); val = g_value_get_int (value); if (val % 2 == 0) val++; @@ -375,32 +383,32 @@ gst_audio_wsincband_set_property (GObject * object, guint prop_id, self->kernel_length = val; gst_audio_wsincband_build_kernel (self); } - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; } case PROP_LOWER_FREQUENCY: - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); self->lower_frequency = g_value_get_float (value); gst_audio_wsincband_build_kernel (self); - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; case PROP_UPPER_FREQUENCY: - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); self->upper_frequency = g_value_get_float (value); gst_audio_wsincband_build_kernel (self); - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; case PROP_MODE: - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); self->mode = g_value_get_enum (value); gst_audio_wsincband_build_kernel (self); - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; case PROP_WINDOW: - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); self->window = g_value_get_enum (value); gst_audio_wsincband_build_kernel (self); - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/gst/audiofx/audiowsincband.h b/gst/audiofx/audiowsincband.h index 977a41f0..b0dea007 100644 --- a/gst/audiofx/audiowsincband.h +++ b/gst/audiofx/audiowsincband.h @@ -60,11 +60,13 @@ typedef struct _GstAudioWSincBandClass GstAudioWSincBandClass; struct _GstAudioWSincBand { GstAudioFXBaseFIRFilter parent; - /* < private > */ gint mode; gint window; gfloat lower_frequency, upper_frequency; gint kernel_length; /* length of the filter kernel */ + + /* < private > */ + GMutex *lock; }; struct _GstAudioWSincBandClass { diff --git a/gst/audiofx/audiowsinclimit.c b/gst/audiofx/audiowsinclimit.c index 68e8522c..1f33ad2d 100644 --- a/gst/audiofx/audiowsinclimit.c +++ b/gst/audiofx/audiowsinclimit.c @@ -26,11 +26,6 @@ * chapter 16 * available at http://www.dspguide.com/ * - * TODO: - Implement the convolution in place, probably only makes sense - * when using FFT convolution as currently the convolution itself - * is probably the bottleneck - * - Maybe allow cascading the filter to get a better stopband attenuation. - * Can be done by convolving a filter kernel with itself */ /** @@ -147,6 +142,7 @@ static void gst_audio_wsinclimit_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_audio_wsinclimit_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_audio_wsinclimit_finalize (GObject * object); static gboolean gst_audio_wsinclimit_setup (GstAudioFilter * base, GstRingBufferSpec * format); @@ -175,6 +171,7 @@ gst_audio_wsinclimit_class_init (GstAudioWSincLimitClass * klass) gobject_class->set_property = gst_audio_wsinclimit_set_property; gobject_class->get_property = gst_audio_wsinclimit_get_property; + gobject_class->finalize = gst_audio_wsinclimit_finalize; /* FIXME: Don't use the complete possible range but restrict the upper boundary * so automatically generated UIs can use a slider */ @@ -211,6 +208,8 @@ gst_audio_wsinclimit_init (GstAudioWSincLimit * self, self->window = WINDOW_HAMMING; self->kernel_length = 101; self->cutoff = 0.0; + + self->lock = g_mutex_new (); } static void @@ -292,6 +291,17 @@ gst_audio_wsinclimit_setup (GstAudioFilter * base, GstRingBufferSpec * format) return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format); } +static void +gst_audio_wsinclimit_finalize (GObject * object) +{ + GstAudioWSincLimit *self = GST_AUDIO_WSINC_LIMIT (object); + + g_mutex_free (self->lock); + self->lock = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + static void gst_audio_wsinclimit_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -304,7 +314,7 @@ gst_audio_wsinclimit_set_property (GObject * object, guint prop_id, case PROP_LENGTH:{ gint val; - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); val = g_value_get_int (value); if (val % 2 == 0) val++; @@ -315,26 +325,26 @@ gst_audio_wsinclimit_set_property (GObject * object, guint prop_id, self->kernel_length = val; gst_audio_wsinclimit_build_kernel (self); } - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; } case PROP_FREQUENCY: - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); self->cutoff = g_value_get_float (value); gst_audio_wsinclimit_build_kernel (self); - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; case PROP_MODE: - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); self->mode = g_value_get_enum (value); gst_audio_wsinclimit_build_kernel (self); - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; case PROP_WINDOW: - GST_OBJECT_LOCK (self); + g_mutex_lock (self->lock); self->window = g_value_get_enum (value); gst_audio_wsinclimit_build_kernel (self); - GST_OBJECT_UNLOCK (self); + g_mutex_unlock (self->lock); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/gst/audiofx/audiowsinclimit.h b/gst/audiofx/audiowsinclimit.h index d30b3938..1a67169e 100644 --- a/gst/audiofx/audiowsinclimit.h +++ b/gst/audiofx/audiowsinclimit.h @@ -60,11 +60,13 @@ typedef struct _GstAudioWSincLimitClass GstAudioWSincLimitClass; struct _GstAudioWSincLimit { GstAudioFXBaseFIRFilter parent; - /* < private > */ gint mode; gint window; gfloat cutoff; gint kernel_length; + + /* < private > */ + GMutex *lock; }; struct _GstAudioWSincLimitClass { -- cgit