mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-18 05:16:05 +00:00
audiofxbasefirfilter: Add property for not draining the history on kernel changes
Currently this only works if the kernel size doesn't change, in the future it will be possible to change the kernel size too without draining the complete history and without loosing anything. Partially based on a patch by Thiago Santos <thiago.sousa.santos@collabora.co.uk>
This commit is contained in:
parent
ed22a97478
commit
a9a5e0c7e1
3 changed files with 51 additions and 18 deletions
|
@ -148,9 +148,6 @@ gst_audio_fir_filter_update_kernel (GstAudioFIRFilter * self, GValueArray * va)
|
|||
gdouble *kernel;
|
||||
guint i;
|
||||
|
||||
gst_audio_fx_base_fir_filter_push_residue (GST_AUDIO_FX_BASE_FIR_FILTER
|
||||
(self));
|
||||
|
||||
if (va) {
|
||||
if (self->kernel)
|
||||
g_value_array_free (self->kernel);
|
||||
|
@ -231,9 +228,7 @@ gst_audio_fir_filter_set_property (GObject * object, guint prop_id,
|
|||
switch (prop_id) {
|
||||
case PROP_KERNEL:
|
||||
g_mutex_lock (self->lock);
|
||||
gst_audio_fx_base_fir_filter_push_residue (GST_AUDIO_FX_BASE_FIR_FILTER
|
||||
(self));
|
||||
|
||||
/* update kernel already pushes residues */
|
||||
gst_audio_fir_filter_update_kernel (self, g_value_dup_boxed (value));
|
||||
g_mutex_unlock (self->lock);
|
||||
break;
|
||||
|
|
|
@ -59,10 +59,12 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
|||
enum
|
||||
{
|
||||
PROP_0 = 0,
|
||||
PROP_LOW_LATENCY
|
||||
PROP_LOW_LATENCY,
|
||||
PROP_DRAIN_ON_CHANGES
|
||||
};
|
||||
|
||||
#define DEFAULT_LOW_LATENCY FALSE
|
||||
#define DEFAULT_DRAIN_ON_CHANGES TRUE
|
||||
|
||||
GST_BOILERPLATE_FULL (GstAudioFXBaseFIRFilter, gst_audio_fx_base_fir_filter,
|
||||
GstAudioFilter, GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
|
||||
|
@ -290,6 +292,8 @@ process_fft_##channels##_##width (GstAudioFXBaseFIRFilter * self, const g##ctype
|
|||
self->buffer_fill = buffer_fill = kernel_length - 1; \
|
||||
} \
|
||||
\
|
||||
g_assert (self->buffer_length == block_length); \
|
||||
\
|
||||
while (input_samples) { \
|
||||
pass = MIN (buffer_length - buffer_fill, input_samples); \
|
||||
\
|
||||
|
@ -505,6 +509,12 @@ gst_audio_fx_base_fir_filter_set_property (GObject * object, guint prop_id,
|
|||
GST_BASE_TRANSFORM_UNLOCK (self);
|
||||
break;
|
||||
}
|
||||
case PROP_DRAIN_ON_CHANGES:{
|
||||
GST_BASE_TRANSFORM_LOCK (self);
|
||||
self->drain_on_changes = g_value_get_boolean (value);
|
||||
GST_BASE_TRANSFORM_UNLOCK (self);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -521,6 +531,9 @@ gst_audio_fx_base_fir_filter_get_property (GObject * object, guint prop_id,
|
|||
case PROP_LOW_LATENCY:
|
||||
g_value_set_boolean (value, self->low_latency);
|
||||
break;
|
||||
case PROP_DRAIN_ON_CHANGES:
|
||||
g_value_set_boolean (value, self->drain_on_changes);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -564,6 +577,22 @@ gst_audio_fx_base_fir_filter_class_init (GstAudioFXBaseFIRFilterClass * klass)
|
|||
"Can only be changed in states < PAUSED!", DEFAULT_LOW_LATENCY,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstAudioFXBaseFIRFilter::drain-on-changes:
|
||||
*
|
||||
* Whether the filter should be drained when its coeficients change
|
||||
*
|
||||
* Note: Currently this only works if the kernel size is not changed!
|
||||
* Support for drainless kernel size changes will be added in the future.
|
||||
*
|
||||
* Since: 0.10.18
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_DRAIN_ON_CHANGES,
|
||||
g_param_spec_boolean ("drain-on-changes", "Drain on changes",
|
||||
"Drains the filter when its coeficients change",
|
||||
DEFAULT_DRAIN_ON_CHANGES,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
trans_class->transform =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_transform);
|
||||
trans_class->start = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_start);
|
||||
|
@ -588,6 +617,7 @@ gst_audio_fx_base_fir_filter_init (GstAudioFXBaseFIRFilter * self,
|
|||
self->nsamples_in = 0;
|
||||
|
||||
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);
|
||||
|
@ -1009,7 +1039,16 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self,
|
|||
g_return_if_fail (self != NULL);
|
||||
|
||||
GST_BASE_TRANSFORM_LOCK (self);
|
||||
if (self->buffer) {
|
||||
|
||||
latency_changed = (self->latency != latency
|
||||
|| (!self->low_latency && self->kernel_length < FFT_THRESHOLD
|
||||
&& kernel_length >= FFT_THRESHOLD)
|
||||
|| (!self->low_latency && self->kernel_length >= FFT_THRESHOLD
|
||||
&& kernel_length < FFT_THRESHOLD));
|
||||
|
||||
/* FIXME: If the latency changes, the buffer size changes too and we
|
||||
* have to drain in any case until this is fixed in the future */
|
||||
if (self->buffer && (!self->drain_on_changes || latency_changed)) {
|
||||
gst_audio_fx_base_fir_filter_push_residue (self);
|
||||
self->start_ts = GST_CLOCK_TIME_NONE;
|
||||
self->start_off = GST_BUFFER_OFFSET_NONE;
|
||||
|
@ -1018,17 +1057,13 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self,
|
|||
self->buffer_fill = 0;
|
||||
}
|
||||
|
||||
latency_changed = (self->latency != latency
|
||||
|| (!self->low_latency && self->kernel_length < FFT_THRESHOLD
|
||||
&& kernel_length >= FFT_THRESHOLD)
|
||||
|| (!self->low_latency && self->kernel_length >= FFT_THRESHOLD
|
||||
&& kernel_length < FFT_THRESHOLD));
|
||||
|
||||
g_free (self->kernel);
|
||||
g_free (self->buffer);
|
||||
self->buffer = NULL;
|
||||
self->buffer_fill = 0;
|
||||
self->buffer_length = 0;
|
||||
if (!self->drain_on_changes || latency_changed) {
|
||||
g_free (self->buffer);
|
||||
self->buffer = NULL;
|
||||
self->buffer_fill = 0;
|
||||
self->buffer_length = 0;
|
||||
}
|
||||
|
||||
self->kernel = kernel;
|
||||
self->kernel_length = kernel_length;
|
||||
|
|
|
@ -62,6 +62,9 @@ struct _GstAudioFXBaseFIRFilter {
|
|||
guint64 latency; /* pre-latency of the filter kernel */
|
||||
gboolean low_latency; /* work in slower low latency mode */
|
||||
|
||||
gboolean drain_on_changes; /* If the filter should be drained when
|
||||
* coeficients change */
|
||||
|
||||
/* < private > */
|
||||
GstAudioFXBaseFIRFilterProcessFunc process;
|
||||
|
||||
|
|
Loading…
Reference in a new issue