From 00ecd06d5cf7ce50e4594846c50f4bbf8084195a Mon Sep 17 00:00:00 2001 From: Rov Juvano Date: Sat, 24 May 2008 00:04:46 -0400 Subject: [PATCH] Move reinit_buffer calls into buffer stream For thread safety and utility, moved calls to reinit_buffers into buffer stream. This way buffers and associated variables get initialized before receiving a buffer to process and remain constant while transforming the buffer. This has the added benefit of allowing parameters to change while playing and without any special code from an app -- the parameters take effect on the next buffer. --- src/gstscaletempo.c | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/gstscaletempo.c b/src/gstscaletempo.c index 1fa54cf..8d0b16e 100644 --- a/src/gstscaletempo.c +++ b/src/gstscaletempo.c @@ -162,6 +162,8 @@ typedef struct _GstScaletempoPrivate { guint (*best_overlap_offset)(GstScaletempo *scaletempo); /* gstreamer */ gint64 segment_start; + /* threads */ + gboolean reinit_buffers; } GstScaletempoPrivate; #define GST_SCALETEMPO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_SCALETEMPO, GstScaletempoPrivate)) @@ -325,26 +327,27 @@ reinit_buffers (GstScaletempo *scaletempo) GstScaletempoPrivate *p = GST_SCALETEMPO_GET_PRIVATE (scaletempo); gint i,j; - if (!p->sample_rate) - return; - guint frames_stride = p->ms_stride * p->sample_rate / 1000.0; p->bytes_stride = frames_stride * p->bytes_per_frame; /* overlap */ guint frames_overlap = frames_stride * p->percent_overlap; if (frames_overlap < 1) { /* if no overlap */ + p->bytes_overlap = 0; p->bytes_standing = p->bytes_stride; p->samples_standing = p->bytes_standing / p->bytes_per_sample; p->output_overlap = NULL; } else { + guint prev_overlap = p->bytes_overlap; p->bytes_overlap = frames_overlap * p->bytes_per_frame; p->samples_overlap = frames_overlap * p->samples_per_frame; p->bytes_standing = p->bytes_stride - p->bytes_overlap; p->samples_standing = p->bytes_standing / p->bytes_per_sample; p->buf_overlap = g_realloc (p->buf_overlap, p->bytes_overlap); p->table_blend = g_realloc (p->table_blend, p->samples_overlap * 4); /* sizeof (gint32|gfloat) */ - memset (p->buf_overlap, 0, p->bytes_overlap); + if (p->bytes_overlap > prev_overlap) { + memset (p->buf_overlap + prev_overlap, 0, p->bytes_overlap - prev_overlap); + } if (p->use_int) { gint32 *pb = p->table_blend; gint64 blend = 0; @@ -418,6 +421,9 @@ reinit_buffers (GstScaletempo *scaletempo) p->bytes_queue_max = new_size; p->buf_queue = g_realloc (p->buf_queue, p->bytes_queue_max); + p->bytes_stride_scaled = p->bytes_stride * p->scale; + p->frames_stride_scaled = p->bytes_stride_scaled / p->bytes_per_frame; + GST_DEBUG ("%.3f scale, %.3f stride_in, %i stride_out, %i standing, %i overlap, %i search, %i queue, %s mode", p->scale, p->frames_stride_scaled, @@ -427,6 +433,8 @@ reinit_buffers (GstScaletempo *scaletempo) p->frames_search, (gint)(p->bytes_queue_max / p->bytes_per_frame), (p->use_int?"s16":"float")); + + p->reinit_buffers = FALSE; } @@ -488,6 +496,9 @@ gst_scaletempo_transform_size (GstBaseTransform *trans, GstScaletempo *scaletempo = GST_SCALETEMPO (trans); GstScaletempoPrivate *priv = GST_SCALETEMPO_GET_PRIVATE (scaletempo); + if (priv->reinit_buffers) + reinit_buffers (scaletempo); + gint bytes_to_out = size + priv->bytes_queued - priv->bytes_to_slide; if (bytes_to_out < (gint)priv->bytes_queue_max) { *othersize = 0; @@ -593,7 +604,7 @@ gst_scaletempo_set_caps (GstBaseTransform *trans, priv->bytes_per_sample = bps; priv->bytes_per_frame = nch * bps; priv->use_int = use_int; - reinit_buffers (scaletempo); + priv->reinit_buffers = TRUE; } return TRUE; @@ -639,15 +650,30 @@ gst_scaletempo_set_property (GObject *object, GstScaletempoPrivate *priv = GST_SCALETEMPO_GET_PRIVATE (scaletempo); switch (prop_id) { - case PROP_STRIDE: - priv->ms_stride = g_value_get_uint (value); + case PROP_STRIDE: { + guint new_value = g_value_get_uint (value); + if (priv->ms_stride != new_value) { + priv->ms_stride = new_value; + priv->reinit_buffers = TRUE; + } break; - case PROP_OVERLAP: - priv->percent_overlap = g_value_get_double (value); + } + case PROP_OVERLAP: { + gdouble new_value = g_value_get_double (value); + if (priv->percent_overlap != new_value) { + priv->percent_overlap = new_value; + priv->reinit_buffers = TRUE; + } break; - case PROP_SEARCH: - priv->ms_search = g_value_get_uint (value); + } + case PROP_SEARCH: { + guint new_value = g_value_get_uint (value); + if (priv->ms_search != new_value) { + priv->ms_search = new_value; + priv->reinit_buffers = TRUE; + } break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -718,6 +744,7 @@ gst_scaletempo_init (GstScaletempo *scaletempo, priv->scale = 0; priv->sample_rate = 0; priv->frames_stride_error = 0; + priv->bytes_stride = 0; priv->bytes_queued = 0; priv->bytes_to_slide = 0; priv->segment_start = 0; -- 2.11.4.GIT