Tidy up locking usage around FFTW.
* Move QMutex into the class instead of static. * Use QMutexLocker * Only lock around FFTW plan & destroy functions.
This commit is contained in:
parent
fdd669360f
commit
fb5181a6e9
|
@ -19,10 +19,12 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QMutex>
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
#include "gstfastspectrum.h"
|
#include "gstfastspectrum.h"
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_fastspectrum_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_fastspectrum_debug);
|
||||||
|
@ -50,8 +52,6 @@ enum {
|
||||||
PROP_BANDS
|
PROP_BANDS
|
||||||
};
|
};
|
||||||
|
|
||||||
static QMutex fftw_mutex;
|
|
||||||
|
|
||||||
#define gst_fastspectrum_parent_class parent_class
|
#define gst_fastspectrum_parent_class parent_class
|
||||||
G_DEFINE_TYPE (GstFastSpectrum, gst_fastspectrum, GST_TYPE_AUDIO_FILTER);
|
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);
|
caps = gst_caps_from_string (ALLOWED_CAPS);
|
||||||
gst_audio_filter_class_add_pad_templates (filter_class, caps);
|
gst_audio_filter_class_add_pad_templates (filter_class, caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
klass->fftw_lock = new QMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -127,8 +129,6 @@ gst_fastspectrum_init (GstFastSpectrum * spectrum)
|
||||||
static void
|
static void
|
||||||
gst_fastspectrum_alloc_channel_data (GstFastSpectrum * spectrum)
|
gst_fastspectrum_alloc_channel_data (GstFastSpectrum * spectrum)
|
||||||
{
|
{
|
||||||
fftw_mutex.lock();
|
|
||||||
|
|
||||||
guint bands = spectrum->bands;
|
guint bands = spectrum->bands;
|
||||||
guint nfft = 2 * bands - 2;
|
guint nfft = 2 * bands - 2;
|
||||||
|
|
||||||
|
@ -139,31 +139,36 @@ gst_fastspectrum_alloc_channel_data (GstFastSpectrum * spectrum)
|
||||||
fftw_malloc(sizeof(fftw_complex) * (nfft/2+1)));
|
fftw_malloc(sizeof(fftw_complex) * (nfft/2+1)));
|
||||||
|
|
||||||
spectrum->spect_magnitude = new double[bands];
|
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<GstFastSpectrumClass*>(
|
||||||
|
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
|
static void
|
||||||
gst_fastspectrum_free_channel_data (GstFastSpectrum * spectrum)
|
gst_fastspectrum_free_channel_data (GstFastSpectrum * spectrum)
|
||||||
{
|
{
|
||||||
|
GstFastSpectrumClass* klass = reinterpret_cast<GstFastSpectrumClass*>(
|
||||||
|
G_OBJECT_GET_CLASS(spectrum));
|
||||||
if (spectrum->channel_data_initialised) {
|
if (spectrum->channel_data_initialised) {
|
||||||
fftw_mutex.lock();
|
{
|
||||||
|
QMutexLocker l(klass->fftw_lock);
|
||||||
fftw_destroy_plan(spectrum->plan);
|
fftw_destroy_plan(spectrum->plan);
|
||||||
|
}
|
||||||
fftw_free(spectrum->fft_input);
|
fftw_free(spectrum->fft_input);
|
||||||
fftw_free(spectrum->fft_output);
|
fftw_free(spectrum->fft_output);
|
||||||
delete[] spectrum->input_ring_buffer;
|
delete[] spectrum->input_ring_buffer;
|
||||||
delete[] spectrum->spect_magnitude;
|
delete[] spectrum->spect_magnitude;
|
||||||
|
|
||||||
spectrum->channel_data_initialised = false;
|
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 bands = spectrum->bands;
|
||||||
guint nfft = 2 * bands - 2;
|
guint nfft = 2 * bands - 2;
|
||||||
|
|
||||||
fftw_mutex.lock();
|
|
||||||
|
|
||||||
for (i = 0; i < nfft; i++)
|
for (i = 0; i < nfft; i++)
|
||||||
spectrum->fft_input[i] =
|
spectrum->fft_input[i] =
|
||||||
spectrum->input_ring_buffer[(input_pos + i) % nfft];
|
spectrum->input_ring_buffer[(input_pos + i) % nfft];
|
||||||
|
|
||||||
|
// Should be safe to execute the same plan multiple times in parallel.
|
||||||
fftw_execute(spectrum->plan);
|
fftw_execute(spectrum->plan);
|
||||||
|
|
||||||
gdouble val;
|
gdouble val;
|
||||||
|
@ -401,8 +405,6 @@ gst_fastspectrum_run_fft (GstFastSpectrum * spectrum, guint input_pos)
|
||||||
val /= nfft * nfft;
|
val /= nfft * nfft;
|
||||||
spectrum->spect_magnitude[i] += val;
|
spectrum->spect_magnitude[i] += val;
|
||||||
}
|
}
|
||||||
|
|
||||||
fftw_mutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
|
|
@ -43,6 +43,8 @@ G_BEGIN_DECLS
|
||||||
#define GST_FASTSPECTRUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_FASTSPECTRUM,GstFastSpectrumClass))
|
#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))
|
#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,
|
typedef void (*GstFastSpectrumInputData)(const guint8* in, double* out,
|
||||||
guint len, double max_value, guint op, guint nfft);
|
guint len, double max_value, guint op, guint nfft);
|
||||||
|
|
||||||
|
@ -84,6 +86,9 @@ struct GstFastSpectrum {
|
||||||
|
|
||||||
struct GstFastSpectrumClass {
|
struct GstFastSpectrumClass {
|
||||||
GstAudioFilterClass parent_class;
|
GstAudioFilterClass parent_class;
|
||||||
|
|
||||||
|
// Static lock for creating & destroying FFTW plans.
|
||||||
|
QMutex* fftw_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_fastspectrum_get_type (void);
|
GType gst_fastspectrum_get_type (void);
|
||||||
|
|
Loading…
Reference in New Issue