From 02a7b31f0e7a9e6630efe925696a9229423314aa Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 1 May 2009 16:47:53 +0100 Subject: [PATCH] audioresample: Fix buffer size transformations When calculating the input/output buffer sizes in the transform_size function, take the number of channels into account, so we don't end up calculating a buffer size that only contains a partial number of audio frames. Also, when going from output size to input size, round down rather than up, so as to calculate the minimum number of samples that *might* yield a buffer of the intended destination size. Fixes: #580470 and #580952 --- gst/audioresample/gstaudioresample.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c index 0cae09e..20e43c1 100644 --- a/gst/audioresample/gstaudioresample.c +++ b/gst/audioresample/gstaudioresample.c @@ -525,7 +525,7 @@ gst_audio_resample_transform_size (GstBaseTransform * base, gboolean ret = TRUE; guint32 ratio_den, ratio_num; gint inrate, outrate, gcd; - gint width; + gint bytes_per_samp, channels; GST_LOG_OBJECT (base, "asked to transform size %d in direction %s", size, direction == GST_PAD_SINK ? "SINK" : "SRC"); @@ -537,37 +537,37 @@ gst_audio_resample_transform_size (GstBaseTransform * base, srccaps = caps; } + /* Get sample width -> bytes_per_samp, channels, inrate, outrate */ ret = - gst_audio_resample_parse_caps (caps, othercaps, &width, NULL, &inrate, - &outrate, NULL); + gst_audio_resample_parse_caps (caps, othercaps, &bytes_per_samp, + &channels, &inrate, &outrate, NULL); if (G_UNLIKELY (!ret)) { GST_ERROR_OBJECT (base, "Wrong caps"); return FALSE; } + /* Number of samples in either buffer is size / (width*channels) -> + * calculate the factor */ + bytes_per_samp = bytes_per_samp * channels / 8; + /* Convert source buffer size to samples */ + size /= bytes_per_samp; + /* Simplify the conversion ratio factors */ gcd = _gcd (inrate, outrate); ratio_num = inrate / gcd; ratio_den = outrate / gcd; if (direction == GST_PAD_SINK) { - gint fac = width / 8; - - /* asked to convert size of an incoming buffer */ - size /= fac; + /* asked to convert size of an incoming buffer. Round up the output size */ *othersize = (size * ratio_den + ratio_num - 1) / ratio_num; - *othersize *= fac; - size *= fac; + *othersize *= bytes_per_samp; } else { - gint fac = width / 8; - - /* asked to convert size of an outgoing buffer */ - size /= fac; - *othersize = (size * ratio_num + ratio_den - 1) / ratio_den; - *othersize *= fac; - size *= fac; + /* asked to convert size of an outgoing buffer. Round down the input size */ + *othersize = (size * ratio_num) / ratio_den; + *othersize *= bytes_per_samp; } - GST_LOG_OBJECT (base, "transformed size %d to %d", size, *othersize); + GST_LOG_OBJECT (base, "transformed size %d to %d", size * bytes_per_samp, + *othersize); return ret; } -- 2.7.4