diff --git a/gst/moodbar/gstfastspectrum.cpp b/gst/moodbar/gstfastspectrum.cpp index 7e9b800a1..6db133107 100644 --- a/gst/moodbar/gstfastspectrum.cpp +++ b/gst/moodbar/gstfastspectrum.cpp @@ -19,10 +19,12 @@ * Boston, MA 02110-1301, USA. */ -#include - #include #include + +#include +#include + #include "gstfastspectrum.h" GST_DEBUG_CATEGORY_STATIC (gst_fastspectrum_debug); @@ -50,8 +52,6 @@ enum { PROP_BANDS }; -static QMutex fftw_mutex; - #define gst_fastspectrum_parent_class parent_class G_DEFINE_TYPE (GstFastSpectrum, gst_fastspectrum, GST_TYPE_AUDIO_FILTER); @@ -111,6 +111,8 @@ gst_fastspectrum_class_init (GstFastSpectrumClass * klass) caps = gst_caps_from_string (ALLOWED_CAPS); gst_audio_filter_class_add_pad_templates (filter_class, caps); gst_caps_unref (caps); + + klass->fftw_lock = new QMutex; } static void @@ -127,8 +129,6 @@ gst_fastspectrum_init (GstFastSpectrum * spectrum) static void gst_fastspectrum_alloc_channel_data (GstFastSpectrum * spectrum) { - fftw_mutex.lock(); - guint bands = spectrum->bands; guint nfft = 2 * bands - 2; @@ -139,31 +139,36 @@ gst_fastspectrum_alloc_channel_data (GstFastSpectrum * spectrum) fftw_malloc(sizeof(fftw_complex) * (nfft/2+1))); spectrum->spect_magnitude = new double[bands]; - spectrum->plan = fftw_plan_dft_r2c_1d( - nfft, - spectrum->fft_input, - spectrum->fft_output, - FFTW_ESTIMATE); - spectrum->channel_data_initialised = true; - fftw_mutex.unlock(); + GstFastSpectrumClass* klass = reinterpret_cast( + G_OBJECT_GET_CLASS(spectrum)); + { + QMutexLocker l(klass->fftw_lock); + spectrum->plan = fftw_plan_dft_r2c_1d( + nfft, + spectrum->fft_input, + spectrum->fft_output, + FFTW_ESTIMATE); + } + spectrum->channel_data_initialised = true; } static void gst_fastspectrum_free_channel_data (GstFastSpectrum * spectrum) { + GstFastSpectrumClass* klass = reinterpret_cast( + G_OBJECT_GET_CLASS(spectrum)); if (spectrum->channel_data_initialised) { - fftw_mutex.lock(); - - fftw_destroy_plan(spectrum->plan); + { + QMutexLocker l(klass->fftw_lock); + fftw_destroy_plan(spectrum->plan); + } fftw_free(spectrum->fft_input); fftw_free(spectrum->fft_output); delete[] spectrum->input_ring_buffer; delete[] spectrum->spect_magnitude; spectrum->channel_data_initialised = false; - - fftw_mutex.unlock(); } } @@ -385,12 +390,11 @@ gst_fastspectrum_run_fft (GstFastSpectrum * spectrum, guint input_pos) guint bands = spectrum->bands; guint nfft = 2 * bands - 2; - fftw_mutex.lock(); - for (i = 0; i < nfft; i++) spectrum->fft_input[i] = spectrum->input_ring_buffer[(input_pos + i) % nfft]; + // Should be safe to execute the same plan multiple times in parallel. fftw_execute(spectrum->plan); gdouble val; @@ -401,8 +405,6 @@ gst_fastspectrum_run_fft (GstFastSpectrum * spectrum, guint input_pos) val /= nfft * nfft; spectrum->spect_magnitude[i] += val; } - - fftw_mutex.unlock(); } static GstFlowReturn diff --git a/gst/moodbar/gstfastspectrum.h b/gst/moodbar/gstfastspectrum.h index 1628a69f5..27579675b 100644 --- a/gst/moodbar/gstfastspectrum.h +++ b/gst/moodbar/gstfastspectrum.h @@ -43,6 +43,8 @@ G_BEGIN_DECLS #define GST_FASTSPECTRUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_FASTSPECTRUM,GstFastSpectrumClass)) #define GST_IS_FASTSPECTRUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_FASTSPECTRUM)) +class QMutex; + typedef void (*GstFastSpectrumInputData)(const guint8* in, double* out, guint len, double max_value, guint op, guint nfft); @@ -84,6 +86,9 @@ struct GstFastSpectrum { struct GstFastSpectrumClass { GstAudioFilterClass parent_class; + + // Static lock for creating & destroying FFTW plans. + QMutex* fftw_lock; }; GType gst_fastspectrum_get_type (void);